如何让chroot在新根文件系统同目录执行命令且正确保留参数?
单脚本实现chroot环境下的正确命令执行(支持空格/通配符参数)
需求很明确:在其他分区的Linux发行版chroot环境中,用名为on的命令,以当前用户身份、主机系统的相同目录执行Shell命令,同时要完美保留带空格或通配符的参数。
原脚本的问题
你最初写的脚本能实现同用户同目录,但遇到带空格的参数就失效:
#!/bin/sh # on: Run a command as the same user in the same directory inside a chroot # Usage: on directory command [args] chrootdir="$1" shift sudo chroot --userspec="`whoami`" "$chrootdir" sh -c "cd \"`pwd`\" && $@"
问题出在sh -c的字符串拼接上:$@在双引号里展开后,会被chroot内的shell重新解析,带空格的参数会被拆分成多个,直接导致命令执行错误。
无需额外chroot脚本的解决方案
不用在每个chroot环境里放runin脚本,单脚本就能搞定。核心是利用shell的位置参数传递,避免字符串拼接带来的解析问题:
#!/bin/sh # on: 在chroot环境中以当前用户身份、主机同目录执行命令 # 用法: on <chroot目录> <命令> [参数...] chrootdir="$1" shift sudo chroot --userspec="$(whoami)" "$chrootdir" sh -c 'cd "$1" && shift && exec "$0" "$@"' -- "$@" "$(pwd)"
脚本原理说明
--用来标记sh命令的位置参数起始点,避免命令或参数以-开头被误识别为shell选项sh -c后的单引号脚本里:"$0"接收的是要执行的命令(比如echo)"$1"是主机上的当前目录,执行cd "$1"切换后,用shift把这个目录参数移除- 剩下的
"$@"就是原命令的所有参数,会原封不动传递给"$0"执行
exec用来替换当前的sh进程,避免多生成一个无用的shell进程
验证示例
比如执行带空格的命令和参数:
on /mnt/ubuntu "echo hello world" "my file with spaces.txt"
这个命令会在/mnt/ubuntu的chroot环境中,切换到你主机当前的目录,以你的用户身份执行echo hello world "my file with spaces.txt",参数里的空格完全保留,不会被拆分。
内容的提问来源于stack exchange,提问作者martinwguy
相关产品推荐
相关产品推荐

