Bash 从标准中读取行时完成时没有失败
Bash While readline from standard in with no failure upon completion
在 bash 中,如果我编写一个执行以下操作的脚本,
while read -r line </dev/stdin; do
...
done | parallel do_something_else
效果很好。没有错误。
但是,当我将脚本放入 make 配方时,make 认为脚本因错误而失败...大概是因为 while 循环在 stdin 结束时失败了。
如何在到达输入末尾时逐行读取 stdin 中的所有行而不返回失败条件?
make
将 运行 每个命令放在单独的 shell 中。考虑:
$ cat Makefile
separate:
echo $$$$
echo $$$$
together:
echo $$$$; \
echo $$$$
$ make separate
echo $$
87214
echo $$
87215
$ make together
echo $$; \
echo $$
87223
87223
请记住,在类似伯恩的 shell(我的默认设置是 bash)中,$$
扩展为 shell 的 PID。但是由于 $
在 Makefile
中也是特殊的,我们必须用它的转义版本 $$
替换每个 $
。因此 $$
变成了 $$$$
,两个美元符号都被替换了。
在 together
目标中,我添加了尾随 \
来防止这种行为。连接这些行后,我还必须在 echo
之间添加一个 ;
。
如果 make
中的任何一个步骤(即单独的命令)失败,make
将在该点失败。因此,如果作业要成功,每个命令都必须 return 0
。但是请注意,在大多数错误情况下,您可能 想要 make
失败。我通常会使用 if
条件来处理 bash 脚本中的这些情况,然后使用 -e
执行脚本,以便显示脚本中的任何错误。
鉴于这些要求和这种行为,我得出结论,到目前为止,编写和调试将由 make
执行的 shell 命令的最简单方法是将其放在一个单独的可执行文件:
$ cat t.sh
#!/bin/bash -e
echo $$
echo $$
$ ls -l ./t.sh
-rwxr-xr-x 1 danfarrell staff 31 Dec 26 16:35 ./t.sh
$ cat Makefile
script:
./t.sh
$ make script
./t.sh
88593
88593
然后您可以选择使用您在 shell 脚本完成时选择的退出代码退出。当您希望 make
认为执行成功时退出 0
。
在 bash 中,如果我编写一个执行以下操作的脚本,
while read -r line </dev/stdin; do
...
done | parallel do_something_else
效果很好。没有错误。
但是,当我将脚本放入 make 配方时,make 认为脚本因错误而失败...大概是因为 while 循环在 stdin 结束时失败了。
如何在到达输入末尾时逐行读取 stdin 中的所有行而不返回失败条件?
make
将 运行 每个命令放在单独的 shell 中。考虑:
$ cat Makefile
separate:
echo $$$$
echo $$$$
together:
echo $$$$; \
echo $$$$
$ make separate
echo $$
87214
echo $$
87215
$ make together
echo $$; \
echo $$
87223
87223
请记住,在类似伯恩的 shell(我的默认设置是 bash)中,$$
扩展为 shell 的 PID。但是由于 $
在 Makefile
中也是特殊的,我们必须用它的转义版本 $$
替换每个 $
。因此 $$
变成了 $$$$
,两个美元符号都被替换了。
在 together
目标中,我添加了尾随 \
来防止这种行为。连接这些行后,我还必须在 echo
之间添加一个 ;
。
如果 make
中的任何一个步骤(即单独的命令)失败,make
将在该点失败。因此,如果作业要成功,每个命令都必须 return 0
。但是请注意,在大多数错误情况下,您可能 想要 make
失败。我通常会使用 if
条件来处理 bash 脚本中的这些情况,然后使用 -e
执行脚本,以便显示脚本中的任何错误。
鉴于这些要求和这种行为,我得出结论,到目前为止,编写和调试将由 make
执行的 shell 命令的最简单方法是将其放在一个单独的可执行文件:
$ cat t.sh
#!/bin/bash -e
echo $$
echo $$
$ ls -l ./t.sh
-rwxr-xr-x 1 danfarrell staff 31 Dec 26 16:35 ./t.sh
$ cat Makefile
script:
./t.sh
$ make script
./t.sh
88593
88593
然后您可以选择使用您在 shell 脚本完成时选择的退出代码退出。当您希望 make
认为执行成功时退出 0
。