Bash 陷阱:cat FILE | 读 A 时;做...退出...完成

TMS*_*TMS 1 unix bash sh

我在编写 bash 脚本时停顿了很长时间,我再次陷入困境:

cat FILE | while read SPID ; do
        if ls $ODIR/*$SPID*.csv > /dev/null 2>&1 ; then
                echo Error: some files exist in the directory $ODIR:
                ls -la $ODIR/*$SPID*.csv
                exit
        fi
done
Run Code Online (Sandbox Code Playgroud)

我很高兴地假设exitbash 脚本会退出整个 bash 脚本,因为它应该退出,但由于它在管道中,它可能只退出分派运行while部分的子进程。

我已经忘记了如何轻松解决此问题。请提醒我!:-)

**编辑:** 现在我已将代码(出于其他原因)更改为使用变量,我正在寻找解决方法:

EXIST="no"
cat FILE | while read SPID ; do
        if ls $ODIR/*$SPID*.csv > /dev/null 2>&1 ; then
                echo Error: some files exist in the directory $ODIR:
                ls -la $ODIR/*$SPID*.csv
                EXIST="yes"
        fi
done
Run Code Online (Sandbox Code Playgroud)

但我想这是同样的情况,我需要使用与运行整个脚本相同的外壳来运行循环内部。

Kam*_*Cuk 7

bash 手动管道

管道中的每个命令都在其自己的子外壳中执行 [...]

的侧面|在子外壳中运行。从父 shell 的子 shell 中看不到环境更改。

( exit; )                   # exits the subshell only
: | exit                    # exits the subshell only
a=1; ( a=5; ); echo $a      # prints 1, a=5 is executed in a subshell
a=1; : | a=5;  echo $a      # prints 1, a=5 is executed in a subshell
Run Code Online (Sandbox Code Playgroud)

将文件通过管道传输到 stdin 以while在父 shell 上下文中执行循环。

 while IFS= read -r spid; do
    ...
 done <file
Run Code Online (Sandbox Code Playgroud)

需要注意的是大写的变量是由出口环境变量,如保留约定IFSLINESCOLUMNSPWDUID等喜欢使用小写的变量。

推荐阅读:我在管道中的循环中设置变量。为什么它们在循环终止后消失?或者,为什么我不能通过管道读取数据?以及如何逐行读取文件