带条件语句的stat命令报错:目录实际存在却提示不存在
问题与解决方案
问题
执行Bash脚本检查并修改远程主机目录权限时,反复收到报错:stat: cannot statx '/usr/share/nginx': No such file or directory found,但已确认远程主机上该目录确实存在。脚本代码如下:
#!/bin/bash test_host=(host) path=/usr/share/nginx for my_hosts in "${test_host}" do ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<EOF if [ ! $(stat -c "%a" "$path") == "664" ] then chmod -R 664 ${path} else echo "permissions were already changed" fi EOF done
原因
脚本中$(stat -c "%a" "$path")的命令替换是在本地主机执行的,而非目标远程主机。默认情况下,Here Document(<<EOF)中的$符号会被本地Shell优先解析,导致本地尝试执行stat命令检查/usr/share/nginx目录,如果本地没有这个目录,就会触发报错。
修复方案
有两种方式解决这个问题:
方式一:转义命令替换中的$符号
将$(stat ...)改为\$(stat ...),让命令替换在远程主机执行,同时保留本地变量$path的替换:
#!/bin/bash test_host=(host) path=/usr/share/nginx for my_hosts in "${test_host}" do ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<EOF if [ ! \$(stat -c "%a" "$path") == "664" ] then chmod -R 664 ${path} else echo "permissions were already changed" fi EOF done
方式二:使用单引号包裹Here Document分界符
用<<'EOF'替代<<EOF,此时Here Document内的所有内容会原封不动发送到远程主机,由远程Shell解析执行。这种情况下需要直接在远程命令中写死路径:
#!/bin/bash test_host=(host) path=/usr/share/nginx for my_hosts in "${test_host}" do ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<'EOF' if [ ! $(stat -c "%a" "/usr/share/nginx") == "664" ] then chmod -R 664 /usr/share/nginx else echo "permissions were already changed" fi EOF done
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

