我正在处理的 Shell 脚本有一个 SQL 查询,该查询从数据库中获取多列和多行:
get_names() {
$ORACLE_HOME/bin/sqlplus -s usr/pwd <<EOF
SELECT id,name,age FROM table;
Exit;
EOF
}
然后,为了读取这个结果,我们通过管道传输函数的输出:
get_names | while read sid p_name p_age ; do ... done
。
现在,由于|
,正在创建一个子 shell,我需要避免这种情况。对于这个问题还有其他替代方案吗?
我们想要破坏该管道语句以避免它的子进程。
答案1
如果您使用的是支持进程替换的 shell(例如 bash、ksh 或 zsh),则可以使用进程替换:
while read sid p_name p_age ; do ...; done < <(get_names)
如果您希望管道的最终链接成为您正在运行的 shell(这样它可能会对您正在运行的 shell 产生影响),那么在 bash 中这是必需的:
for sh in bash ksh zsh; do
echo $sh:; $sh -c 'while read var; do i=$var
done < <(printf "%s\n" 1 2); echo $i '
done
输出:
bash:
2
ksh:
2
zsh:
2
而对于常规管道:
for sh in bash ksh zsh; do
echo $sh:; $sh -c 'printf "%s\n" 1 2 |
while read var; do i=$var; done ; echo $i ';
done
分配不固定,因为 bash 在子 shell 中而不是在当前 shell 中运行 while 循环:
bash:
ksh:
2
zsh:
2
答案2
您可以在一个 python 进程中完成这一切(也可以使用其他语言)。