![将 sed 的输出作为接受输入的 bash 脚本执行](https://linux22.com/image/216628/%E5%B0%86%20sed%20%E7%9A%84%E8%BE%93%E5%87%BA%E4%BD%9C%E4%B8%BA%E6%8E%A5%E5%8F%97%E8%BE%93%E5%85%A5%E7%9A%84%20bash%20%E8%84%9A%E6%9C%AC%E6%89%A7%E8%A1%8C.png)
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
/tmp
generate.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)