我有一个复杂的命令,我试图在 docker 内部运行。它设置现有用户的 uid,chroot 到某个目录,并在那里执行“可能很复杂的命令”。
docker (compose with stuff) run container /bin/bash -c "setuidgid.sh a:b && exec sudo -u user1 /bin/bash -c \" mkdir -p /chrootdir/proc && cp /proc/cpuinfo /chrootdir/proc/cpuinfo && sudo chroot /chrootdir echo hi1 && /bin/bash -c \\\"echo hi2 && /bin/bash -c \\\\\\\"echo hi3\\\\\\\"\\\"\" "
我在这里得到了预期的输出 - 每一层嵌套都会去掉一对反斜杠字符。然而,生成的命令非常丑陋且难以阅读。有没有更好的方法来实现这一目标? (我已经使这个命令专门嵌套了很多,我的代码中不应该达到需要超过“hi2”的点。这个命令只是为了提问)
注意:我不想使用单引号,因为这个最里面的命令将调用一些我事先可能不知道的任意命令。可以保证不使用双引号,但可以使用单引号。
PS。对命令本身的任何改进都可以留在评论中。当前解决方案有一些原因,即使可以找到量身定制的解决方案,我的主要目标是弄清楚如何为任意命令嵌套引号。 附言。我不认为这是重复的,因为有关该主题的大多数其他问题都在替换 $() 中使用嵌套引号。
当您使用
sudo
运行一些内联“脚本”时,就不可能使用导出函数,但是 ${var@Q}
(或 printf %q "$var"
)可以帮助使嵌套引用不易出错:
您原来的命令:
docker ... run container /bin/bash -c "
setuidgid.sh a:b &&
exec sudo -u user1 /bin/bash -c \"
mkdir -p /chrootdir/proc &&
cp /proc/cpuinfo /chrootdir/proc/cpuinfo &&
sudo chroot /chrootdir echo hi1 &&
/bin/bash -c \\\"
echo hi2 &&
/bin/bash -c \\\\\\\"
echo hi3
\\\\\\\"
\\\"
\"
"
用
${var@Q}
重构命令:
sh3="
echo hi3
"
sh2="
echo hi2 &&
/bin/bash -c ${sh3@Q}
"
sh1="
mkdir -p /chrootdir/proc &&
cp /proc/cpuinfo /chrootdir/proc/cpuinfo &&
sudo chroot /chrootdir echo hi1 &&
/bin/bash -c ${sh2@Q}
"
sh0="
setuidgid.sh a:b &&
exec sudo -u user1 /bin/bash -c ${sh1@Q}
"
docker ... run container /bin/bash -c "$sh0"