SSH执行远程服务器Shell脚本时提示docker: command not found
问题现象
通过SSH连接远程服务器执行含docker命令的Shell脚本时,手动登录服务器执行docker命令正常,但脚本运行抛出docker: command not found错误,报错日志如下:
+ eloquent_shamir + echo eloquent_shamir + docker version /tmp/nmon_jstat_scripts_to_container.sh: line 4: docker: command not found copying nmon.sh in container:eloquent_shamir + echo 'copying nmon.sh in container:eloquent_shamir' + docker cp /tmp/nmon.sh eloquent_shamir:/opt/ /tmp/nmon_jstat_scripts_to_container.sh: line 6: docker: command not found copying jstat.sh in container:eloquent_shamir + echo 'copying jstat.sh in container:eloquent_shamir' + docker cp /tmp/jstat.sh eloquent_shamir:/opt/ /tmp/nmon_jstat_scripts_to_container.sh: line 9: docker: command not found + docker exec -it eloquent_shamir /bin/bash -c 'chmod 777 /opt/nmon.sh' /tmp/nmon_jstat_scripts_to_container.sh: line 12: docker: command not found + docker exec -it eloquent_shamir /bin/bash -c 'chmod 777 /opt/jstat.sh' /tmp/nmon_jstat_scripts_to_container.sh: line 14: docker: command not found
原执行脚本内容(传入参数eloquent_shamir为目标Docker容器名):
#!/bin/bash -x echo $1 docker version echo "copying nmon.sh in container:$1" docker cp /tmp/nmon.sh $1:/opt/ echo "copying jstat.sh in container:$1" docker cp /tmp/jstat.sh $1:/opt/ docker exec -it $1 /bin/bash -c "chmod 777 /opt/nmon.sh" docker exec -it $1 /bin/bash -c "chmod 777 /opt/jstat.sh" echo "...................." echo "creating NMON_OUTPUT dir in container:$1" docker exec -it $1 /bin/bash -c "mkdir /opt/NMON_OUTPUT" echo "creating JSTAT_OUTPUT dir in container:$1" docker exec -it $1 /bin/bash -c "mkdir /opt/JSTAT_OUTPUT" echo "...................." sleep 10
问题原因
手动登录服务器属于交互式Shell会话,会自动加载/etc/profile、~/.bashrc等环境配置文件,docker的安装路径会被加入PATH变量,所以可以直接执行docker命令。
通过SSH非交互式执行脚本时,不会加载上述环境配置,PATH变量默认只包含/usr/bin:/bin等基础路径,如果docker安装在/usr/local/bin等非默认基础路径下,就会出现找不到命令的报错。
另外脚本中docker exec带了-it参数,非交互式环境下没有分配tty终端,解决路径问题后还会触发tty相关报错。
解决方案
优先选择前两种方案,兼容性最好:
- 方案1:脚本内使用docker绝对路径
先手动登录远程服务器,执行which docker查询docker的完整安装路径,常见返回值为/usr/bin/docker或/usr/local/bin/docker,将脚本中所有docker替换为查询到的全路径即可。 - 方案2:脚本开头手动补充PATH环境变量
在脚本第一行#!/bin/bash -x下方新增一行,把docker常见安装路径加入PATH:export PATH=$PATH:/usr/bin:/usr/local/bin - 额外必改项:去掉
docker exec的tty参数
把脚本中所有docker exec -it改成docker exec(仅需要执行命令不需要交互的场景直接去掉t参数即可),避免非交互环境下tty报错。
修改后的可用脚本参考:
#!/bin/bash -x export PATH=$PATH:/usr/bin:/usr/local/bin echo $1 docker version echo "copying nmon.sh in container:$1" docker cp /tmp/nmon.sh $1:/opt/ echo "copying jstat.sh in container:$1" docker cp /tmp/jstat.sh $1:/opt/ docker exec $1 /bin/bash -c "chmod 777 /opt/nmon.sh" docker exec $1 /bin/bash -c "chmod 777 /opt/jstat.sh" echo "...................." echo "creating NMON_OUTPUT dir in container:$1" docker exec $1 /bin/bash -c "mkdir /opt/NMON_OUTPUT" echo "creating JSTAT_OUTPUT dir in container:$1" docker exec $1 /bin/bash -c "mkdir /opt/JSTAT_OUTPUT" echo "...................." sleep 10
内容的提问来源于stack exchange,提问作者Ayushman Sharma
相关产品推荐
相关产品推荐

