的bash命令行标准输入是如何传播到子进程

问题描述:

我有一个脚本(file_redirection.sh),在那里我曾尝试各种组合来得到我想要的:的bash命令行标准输入是如何传播到子进程

#!/bin/bash 
echo "cat " $* 
echo "cat $*" 
echo "cat [email protected]" 
echo "cat " [email protected] 

我想能够运行

file_redirection.sh < tmp_file 

,并让它显示

"cat < tmp_file" 

这可能吗?

你问“它是如何工作的”。 UNIX进程使用名为fork的操作创建。这需要当前过程的副本,并以非常有效的方式几乎完全按照原样复制它。复制还包括文件描述符表,其中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。你为什么要这么做?

+0

谢谢你的回答。在我问之后,我碰到过[-t 0],但我不知道fd表。 我想要这个,因为qrsh似乎不适合重定向stdin,但是如果我在给予qrsh的命令中进行重定向,那么一切都很好。 'qrsh“cmd” esmit 2013-03-13 05:34:34

+0

注意自我:我几乎提出了一个新问题,为什么'file'指向一个带有'(deleted) '附加,但是在这个周末,这个问题似乎已经解决了。 – esmit 2016-04-25 18:00:44

不,这是不可能的。命令行上的<在您的脚本运行之前由shell解释。您需要跳过<才能将其加入脚本。例如:

file_redirection.sh \< tmp_file 

会产生你要找的输出,但做任何文件重定向。

+0

虽然这回答了我的问题'是否有可能?'(这就是为什么我将其标记为正确的原因),它不能帮助我将重定向的stdin传递给子进程。我应该问这是一个单独的问题还是编辑这个问题? – esmit 2013-03-12 20:06:52

使用此:

file_redirection.sh "< tmp_file"

,并在文件中这样的:

echo "cat $1"

OR

file_redirection.sh \< tmp_file

,并在文件中这样的:

echo "cat $*"

+0

您正在改变输入以获得所需的输出,而不是(不可能,因为它变成了)改变脚本以从给定输入产生期望的输出。 – chepner 2013-03-12 19:30:51