如何通过SSH配置以其他用户身份启动带临时函数的交互式Bash Shell?
解决SSH切换用户后临时函数无法调用的问题
问题原因
你使用的进程替换<(...)是由登录用户login-user创建的匿名管道,当通过sudo -Hu admin-user切换用户后,admin-user的Bash进程因权限限制或sudo的默认文件描述符配置,无法访问该管道,导致初始化命令中的函数定义未被执行,因此交互式shell中找不到testy函数。
解决方案
方案1:通过标准输入传递初始化脚本
修改SSH配置中的RemoteCommand,用标准输入替代进程传递初始化命令,避免权限问题:
HOST SYSTEM Hostname 12.34.56.78 User login-user RemoteCommand sudo -Hu admin-user bash --init-file /dev/stdin -li <<'EOF' . ~/.bashrc testy() { ls; } EOF
或者更简洁的管道写法:
HOST SYSTEM Hostname 12.34.56.78 User login-user RemoteCommand sudo -Hu admin-user echo -e '. ~/.bashrc\ntesty() { ls; }' | bash --init-file /dev/stdin -li
原理:bash --init-file /dev/stdin会从标准输入读取初始化命令,先加载admin-user的bashrc,再定义临时函数,最后启动交互式shell,整个流程在admin-user的权限环境下执行,无管道访问问题。
方案2:导出函数后启动交互式shell
利用export -f将函数导出为环境变量,让后续交互式shell继承该函数:
HOST SYSTEM Hostname 12.34.56.78 User login-user RemoteCommand sudo -Hu admin-user bash -c '. ~/.bashrc; testy() { ls; }; export -f testy; exec bash -li'
原理:先在非交互式shell中加载admin-user的bashrc并定义函数,通过export -f将函数导出到环境变量,再用exec bash -li替换当前进程为交互式shell,交互式shell会继承导出的函数,同时-li参数确保加载bashrc。
内容的提问来源于stack exchange,提问作者Patrick Geery
相关产品推荐
相关产品推荐

