shell 如何保持bash会话打开并交互执行命令?

evrscar2  于 2023-10-23  发布在  Shell
关注(0)|答案(1)|浏览(170)

我正在实现自定义的gitlab-runer执行器。Gitlab发送多个脚本按顺序执行,并希望在同一个shell会话中执行它们。但是,我的 Package 器脚本会执行多次。
虽然我可以执行bash -s <script_from_gitlab.sh,但这将在一个 * 新 * 环境中执行多个脚本。我想保持像一个“bash服务”运行一个开放的输入和输出,运行一个命令,然后当一个命令完成收集输出并显示它,同时保持环境。这与Python中的Jupiter notebook非常相似。
如何实现这样的“持久bash会话”,并在该会话中执行 one 命令,并以非交互方式收集其输出?
我唯一的想法是用uuid分隔输出:

  1. #!/bin/bash
  2. prepare() {
  3. # runs a bash in the background waiting for commands
  4. mkfifo /tmp/fifoin /tmp/fifoout
  5. bash -s </tmp/fifoin >/tmp/fifoout &
  6. echo $! > /tmp/bashpid
  7. }
  8. run() {
  9. mark=d1c21272-4055-4cd4-a0d4-3462e7d29373
  10. {
  11. # executes script
  12. cat "$1"
  13. echo "$mark"
  14. } > /tmp/fifoin &
  15. while IFS= read -r line; do
  16. if [[ "$line" == "$mark" ]]; then
  17. break
  18. fi
  19. printf "%s\n" "$line"
  20. done
  21. }
  22. cleanup() {
  23. pid=$(</tmp/bashpid)
  24. kill "$pid"
  25. tail -f --pid "$pid"
  26. }
  27. # executed with arguments: "cleanup" "run thiscript" "run thatscript" "cleanup" in order
  28. "$1" "$2"

然而,这感觉像是一种变通方法,特别是使用“标记”来获取脚本是否完成执行。有别的解决办法吗?
在真实的生活中,这些命令是由Nomad调度程序运行的。这是相同的,只是bash -snomad exec <allocid> bash -s一起执行。

wh6knrhe

wh6knrhe1#

这是一个尝试,希望它能适应您的要求:

  1. #!/bin/sh
  2. input=/tmp/pipe-input
  3. output=/tmp/pipe-output
  4. # Wait for commands from $input and send results to $output
  5. server(){
  6. rm -f $input $output
  7. mkfifo $input $output
  8. while true; do
  9. echo "Hello from server." >&2
  10. eval "$(cat $input)" > $output
  11. done
  12. }
  13. client(){
  14. cat > $input; cat $output
  15. }
  16. # Send commands to server every second.
  17. test-client(){
  18. for i in {1..6}; do
  19. client <<< 'echo $(date +%T) server hostname=$(hostname), server bash PID=$$'
  20. sleep 1
  21. done
  22. client <<< 'exit'
  23. }
  24. "$@"

在一个窗口中,运行

  1. bash test.sh server

在另一个窗口中,运行

  1. bash test.sh test-client

我认为eval的使用是“可以容忍的”,因为你可以控制命令的运行。

展开查看全部

相关问题