我有以下脚本
ssh user@host << EOF
STATUS="$(git status)"
SEARCH_STATUS="Not a git"
if [[ "$STATUS" == *$SEARCH_STATUS* ]]; then
echo "Not a git repository"
fi
EOF
我收到以下错误
-bash: line 3: file: No such file or directory
对应这一行
STATUS="$(git status)"
这里的问题是,上面的行正在工作,git 确实存在,并且正在按计划执行,并将 git 命令的输出存储在 STATUS 中,并且 If 语句也按计划执行,这回显了状态git 匹配“Not a git”字符串...
我不明白的是,为什么它会抛出这个错误,有什么想法吗?
答案1
shell 正在扩展您机器上的命令,而不是远程机器上的命令。
引用“EOF”
ssh user@host<<'EOF'
STATUS="$(git status)"
EOF
从man bash
:
这里的文件
这种类型的重定向指示 shell 从当前源读取输入,直到看到仅包含分隔符(没有尾随空格)的行。到该点读取的所有行都将用作命令的标准输入。
这里文档的格式是:
<<[-]word here-document delimiter
不对 word 执行任何参数扩展、命令替换、算术扩展或路径名扩展。如果word中的任何字符被引用,则分隔符是word删除引号的结果,并且此处文档中的行不会被扩展。 如果 word 不加引号,则此处文档的所有行都将进行参数扩展、命令替换和算术扩展。在后一种情况下,字符序列 \ 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `。
编辑
你的测试也是错误的。您可以使用grep
检查所需的字符串是否在输出中:
ssh user@host <<'EOF'
if git status 2>&1 | grep -q 'Not a git' ; then
echo 'Not a git repository'
fi
EOF
或者如果您想保留变量中的状态
ssh user@host <<'EOF'
STATUS=$(git status 2>&1)
if echo $STATUS | grep -q 'Not a git' ; then
echo 'Not a git repository'
fi
EOF
请注意,您必须重定向STDERR
到STDOUT
2>&1
编辑2
如果你强迫bash
也可以
ssh user@host bash <<'EOF'
STATUS=$(git status 2>&1)
SEARCH_STATUS="ot a git"
echo "STATUS=$STATUS"
if [[ "$STATUS" == *$SEARCH_STATUS* ]]; then
echo 'Not a git repository'
fi
EOF
请注意,在 macOS 和 Linux 上,“Not”/“not”的大小写不同。因此,SEARCH_STATUS
是正义的ot a git
,而不是正义的Not a git