将 sed 的输出作为接受输入的 bash 脚本执行

将 sed 的输出作为接受输入的 bash 脚本执行
sed 's/docker/sudo docker/g' ./generate.sh | xargs bash

我想运行一个脚本generate.sh,将所有docker调用替换为sudo docker,就像我调用 时它会运行一样bash generate.sh。它也需要用户输入,那么我如何让它工作呢?我无法保存任何文件,只能使用终端。

答案1

如果,正如您对 @Freddy 现在已删除的答案所评论的那样,临时生成的脚本的路径位于当前工作目录中也很重要,因为脚本会查找相对于其自身路径的其他资源,这样的操作将不起作用:

bash <(sed 's/docker/sudo docker/g' ./generate.sh)

因为脚本的路径将类似于/dev/fd/63或,并且脚本将在或/tmp/some-temporary-named-pipe中查找资源,而不是当前工作目录所在的目录。/dev/fd/tmpgenerate.sh

但是,在 zsh 中,您可以执行以下操作:

TMPPREFIX=$PWD/.transformed-
bash =(sed 's/docker/sudo &/g' ./generate.sh)

其中=(...)命令替换的形式使用临时文件而不是/dev/fd/x和 管道,并且可以告诉如何使用$TMPPREFIX$TMPSUFFIX变量来命名它们。

local或者仅在匿名函数中修改 ly 变量:

() { local TMPPREFIX=$PWD/.transformed-
bash =(sed 's/docker/sudo &/g' ./generate.sh)
}

在 bash 中,也许你可以这样做:

docker() { sudo docker "$@"; }
export -f docker
bash ./generate.sh

相反,重新定义docker为调用sudo docker.

但请注意,导出的函数最终也会导出到该脚本运行的其他命令。

第一次使用时取消导出可能是明智的做法,以限制它们进一步传播的风险:

docker() {
  typeset -f +x docker
  sudo docker "$@"
}
export -f docker
bash ./generate.sh

请注意,无论如何,导出的函数都不会存活下来sudo(谢天谢地!)。

或者使用:

bash -c 'docker() { sudo docker "$@"; }; . ./generate.sh'

这甚至可以工作sh(该.sh扩展表明它是一个 sh 脚本):

sh -c 'docker() { sudo docker "$@"; }; . ./generate.sh' ./generate.sh

其中第二个./generate.sh作为内联脚本传递$0 (这可能是您的脚本了解其自己的路径是什么的地方)。

如果脚本足够短,您可以将sed的输出作为一个整体作为内联脚本传递:

bash -c "$(sed 's/docker/sudo &/g' ./generate.sh)" ./generate.sh

在 ksh 模拟中,zsh可以解释大多数 bash 脚本,而 zsh 可以让您重新定义$0,因此您可以执行以下操作:

zsh --emulate ksh <(
  echo '0=./generate.sh'; sed 's/docker/sudo &/g' ./generate.sh)

相关内容