多次更改脚本中的 shell

多次更改脚本中的 shell

我想要一个可以获取命令列表、逐一执行它们并显示输出的脚本。问题是某些命令将启动新的 shell,这应该会影响后续命令。我在名为 的文件中有一些示例输入commands

echo "current shell: $0"
ksh
echo "current shell: $0"
exit
echo "current shell: $0"

我有这个脚本,test3.sh它使用命名管道来发送命令。

#! /usr/bin/env bash

# Create a pipe for processing commands
rm -f shell-pipe
mkfifo shell-pipe

# Set up a bash shell to process the commands sent to the pipe
(tail -f shell-pipe | bash) &

while IFS='' read -r command; do
  echo ">>> sending command: $command"
  echo $command > shell-pipe
  sleep 1
done

# Close the pipe and delete it
fuser -TERM -k shell-pipe > /dev/null
rm shell-pipe

有用。

$ ./test3.sh < commands
>>> sending command: echo "current shell: $0"
current shell: bash
>>> sending command: ksh
>>> sending command: echo "current shell: $0"
current shell: ksh
>>> sending command: exit
>>> sending command: echo "current shell: $0"
current shell: bash

但我事先不知道命令需要多长时间才能完成,所以我需要某种方法来确定命令是否已完成。所以我为响应设置了一个单独的命名管道。

$ cat test4.sh
#! /usr/bin/env bash

# Create a pipe for processing commands
rm -f shell-pipe response-pipe
mkfifo shell-pipe response-pipe

# Set up a bash shell to process the commands sent to the pipe
(tail -f shell-pipe | bash > response-pipe) &

while IFS='' read -r command; do
  echo ">>> sending command: $command"
  echo $command > shell-pipe
  echo "...waiting for response..."
  echo "<<< reponse: " $(cat response-pipe)
done

# Close the pipe and delete it
fuser -TERM -k shell-pipe > /dev/null
rm shell-pipe response-pipe

不幸的是,这个挂起,最终我不得不使用 Ctrl-c。

$ ./test4.sh < commands
>>> sending command: echo "current shell: $0"
...waiting for response...
^C

我尝试过使用该exec命令,但这没有帮助。我bash在这个例子中使用了,但很乐意使用另一个 shell、Python 或 Haskell。

答案1

如果您将其运行为(或任何一次bash < file处理一行输入的 shell ),那么这将起作用:read

$ cat file
echo "current shell: $0"
ksh
echo "current shell: $0"
exit
echo "current shell: $0"
$ bash < file
current shell: bash
current shell: ksh
current shell: bash
$ zsh < file
current shell: zsh
current shell: ksh
current shell: zsh

(不适用于dash在开始解释它所读取的内容之前读取整个文件(至少 8KiB 块)(不进行 bash 或 ksh 所做的搜索),因此 ksh 在启动时没有什么可读取的) 。

请注意,如果任何调用的命令(不仅仅是 shell)读取其标准输入,它们也会从脚本中读取,例如

export VAR=before
echo "$0 $VAR"
ksh
echo "$0 $VAR"
read VAR
after
echo "$0 $VAR"
exit
echo "$0 $VAR"

你会得到:

bash before
ksh before
ksh after
bash before

相关内容