我正在尝试将 tail 命令的输出通过管道传输到另一个 bash 脚本中以进行处理:
tail -n +1 -f your_log_file | myscript.sh
但是,当我运行它时,$1 参数(在 myscript.sh 中)永远不会到达。我错过了什么?如何通过管道将输出作为脚本的输入参数?
PS - 我希望 tail 永远运行并继续将每一行传递到脚本中。
编辑 现在 myscripts.sh 的全部内容是:
echo $1;
我正在尝试将 tail 命令的输出通过管道传输到另一个 bash 脚本中以进行处理:
tail -n +1 -f your_log_file | myscript.sh
但是,当我运行它时,$1 参数(在 myscript.sh 中)永远不会到达。我错过了什么?如何通过管道将输出作为脚本的输入参数?
PS - 我希望 tail 永远运行并继续将每一行传递到脚本中。
编辑 现在 myscripts.sh 的全部内容是:
echo $1;
通常,这是处理脚本标准输入的一种方法:
#!/bin/bash
while read line; do
echo $line
done
这是一个非常粗糙的 bash,相当于cat
. 它确实证明了一个关键事实:脚本中的每个命令都从 shell 继承其标准输入,因此您实际上不需要做任何特殊的事情来访问传入的数据。read
从 shell 获取输入,其中(在您的案例)正在从tail
通过管道连接到它的进程中获取输入。
作为另一个例子,考虑这个脚本;我们将其称为“mygrep.sh”。
#!/bin/bash
grep "$1"
现在管道
some-text-producing-command | ./mygrep.sh bob
行为相同
some-text-producing-command | grep bob
$1
如果您像这样调用脚本,则会设置:
./myscript.sh foo
然后$1
具有值“foo”。
位置参数和标准输入是分开的;你可以这样做
tail -n +1 -f your_log_file | myscript.sh foo
现在标准输入仍然来自tail
进程,并且$1
仍然设置为'foo'。
也许您对此感到困惑awk
?
tail -n +1 -f your_log_file | awk '{
print $1
}'
将从 tail 命令的输出中打印第一列。
在 shell 中,可以通过以下方式实现类似的效果:
tail -n +1 -f your_log_file | while read first junk; do
echo "$first"
done
或者,您可以将整个while ... done
循环放在里面myscript.sh
管道将一个进程的输出 ( stdout
) 连接到另一个进程的输入 ( stdin
)。stdin
与启动时发送给进程的参数不同。
您要做的是将第一个进程的输出中的行转换为第二个进程的参数。这正是xargs命令的用途。
您需要做的就是xargs
在初始命令之间插入一个管道,它将起作用:
tail -n +1 -f your_log_file | xargs | myscript.sh