gpt4 book ai didi

linux - Bash 子 shell 使用父进程的标准输入

转载 作者:太空狗 更新时间:2023-10-29 11:36:02 25 4
gpt4 key购买 nike

假设我有一个 main.sh 脚本,它将通过子 shell 调用 one.sh

one.sh:

#! /bin/bash

set -euo pipefail

(if [ -t 0 ]; then
echo "one little two little three little buses"
else
cat -
fi) | awk '{ $1 = "111"; print $0 }'

main.sh:

#! /bin/bash                                                

set -euo pipefail

main() {
echo "one_result) $(./one.sh)"

echo "one_piped) $(echo "the quick brown fox" | ./one.sh)"
}

main

现在,它们每个都按预期工作:

$ ./one.sh
111 little two little three little buses

$ ./main.sh
one_result) 111 little two little three little buses
one_piped) 111 quick brown fox

但是,当我将某些内容通过管道传输到 main.sh 时,我并不期望(或者更确切地说,我不希望)one.sh 了解管道内容,因为我认为 one.shone_result) 中它自己的子 shell 中:

$ echo "HELLO WORLD MAIN" | ./main.sh                                                                                
one_result) 111 WORLD MAIN
one_piped) 111 quick brown fox

是不是我在 one.sh 中的 if 条件不是我想要的?我希望 one.sh 在使用我的 main.sh 的标准输入时不会产生任何副作用 - 因为现在它已经使用了它,我的 main. sh 现在实际上是 stdin-less,因为 stdin 只能读取一次,除非我将其存储起来。

想法? TIA。

最佳答案

通常,子 shell(以及 shell 生成的其他进程)从父 shell 继承标准输入。如果那是终端,那么您的测试将按预期进行;如果它是一个管道,那么它会检测到它是一个管道并继续使用它。子 shell 无法通过显式分配(如 echo "the quick brown fox"| ./one.sh)或通过继承来判断它是否获得了该管道。

据我所知,避免此问题的唯一方法是将 one.sh 的输入显式重定向到管道以外的其他内容,以避免它继承父 shell 的标准输入(可能是一个管道)。像这样的东西:

echo "one_nonpipe) $(./one.sh </dev/null)"                            

echo "one_piped) $(echo "the quick brown fox" | ./one.sh)"

...但是更好的是添加一个标志来告诉 one.sh 是否从 stdin 读取,而不是试图从类型中找出它附加到标准输入的文件:

#! /bin/bash
# Usage: one.sh [-i]
# -i Read from stdin

set -euo pipefail

if [ "$1" = "-i" ]; then
cat -
else
echo "one little two little three little buses"
fi | awk '{ $1 = "111"; print $0 }'

...

echo "one_result) $(./one.sh)"

echo "one_piped) $(echo "the quick brown fox" | ./one.sh -i)"

(请注意,我还删除了 if block 周围不必要的括号——他们无缘无故地创建了另一层子 shell。)

关于linux - Bash 子 shell 使用父进程的标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38133153/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com