我有一个脚本 ( file_redirection.sh
),我尝试了各种组合来获得我想要的东西:
#!/bin/bash
echo "cat " $*
echo "cat $*"
echo "cat $@"
echo "cat " $@
我希望能够跑步
file_redirection.sh < tmp_file
并让它显示
"cat < tmp_file"
那可能吗?
我有一个脚本 ( file_redirection.sh
),我尝试了各种组合来获得我想要的东西:
#!/bin/bash
echo "cat " $*
echo "cat $*"
echo "cat $@"
echo "cat " $@
我希望能够跑步
file_redirection.sh < tmp_file
并让它显示
"cat < tmp_file"
那可能吗?
不,那是不可能的。在<
你的脚本运行之前,你的命令行上的 由 shell 解释。您需要转义<
以将其放入您的脚本中。例如:
file_redirection.sh \< tmp_file
将生成您正在寻找的输出,但不执行任何文件重定向。
你问“它是如何工作的”。UNIX 进程是使用称为 的操作创建的fork
。这会以非常有效的方式获取当前进程的副本并几乎完全按原样复制它。复制还包括文件描述符表,其中 stdin、stdout、stderr 存在。
当您进行重定向时,shell 会分叉,然后在子进程中更改它自己的文件描述符 (fd) 表。然后它在同一进程中使用相同的 fd 表运行新脚本。使用传统机制,进程唯一可以检查的是标准输入是否连接到终端。在 C 中它使用它isatty()
,而在 bash 中你可以if [[ -t 0 ]]...
(零是标准输入的 fd)。
在 Linux 中(如果您使用的是 Linux),您还有一个附加选项,fd 表以可读的形式呈现在/proc/$$/fd
($$ 给出当前进程 id)中。 ls -l /proc/$$/fd
你会明白我的意思。
那么,我被重定向了吗?
if [[ -t 0 ]] # is stdin a terminal?
then
suffix=""
else
line=$(ls -l /proc/$$/fd/0)
file="${line##*-> }"
suffix="< $file"
fi
echo "cat $suffix"
在命令行上:
/home/user1$ file_redirection.sh < tmp_file
cat < /home/qa/tmp_file
但。你到底为什么要这么做?
用这个:
file_redirection.sh "< tmp_file"
在你的文件中:
echo "cat $1"
或者
file_redirection.sh \< tmp_file
在你的文件中:
echo "cat $*"