bash命令行stdin如何传播到子进程

时间:2013-03-12 18:33:35

标签: bash

我有一个脚本(file_redirection.sh),在那里我尝试了各种组合来获得我想要的东西:

#!/bin/bash
echo "cat " $*
echo "cat $*"
echo "cat $@"
echo "cat " $@

我希望能够运行

file_redirection.sh < tmp_file

让它显示

"cat < tmp_file"

这可能吗?

3 个答案:

答案 0 :(得分:6)

不,那是不可能的。在脚本运行之前,shell会解释命令行上的<。您需要转义<才能将其放入脚本中。例如:

file_redirection.sh \< tmp_file

将生成您正在寻找的输出,但不会执行任何文件重定向。

答案 1 :(得分:4)

你问“它是如何工作的”。使用称为fork的操作创建UNIX进程。这需要当前进程的副本,并以非常有效的方式几乎完全复制它。复制还包括文件描述符表,其中stdin,stdout,stderr,live。

当你进行重定向时,shell会分叉,然后在子代码中改变它自己的文件描述符(fd)表。然后它在同一进程中使用相同的fd表运行新脚本。使用传统机制,进程唯一可以检查的是stdin是否连接到终端。在C中它使用isatty(),在bash中你可以if [[ -t 0 ]]...(零是stdin的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

BUT。为什么你想这样做?

答案 2 :(得分:-1)

使用此:

file_redirection.sh "< tmp_file"

并在您的文件中:

echo "cat $1"

OR

file_redirection.sh \< tmp_file

并在您的文件中:

echo "cat $*"

相关问题