Jan*_*ith 9 ssh command-line bash
我有一个if语句来计算文件并删除除最新的三个文件之外的所有文件。但我想远程运行这个命令。我怎样才能ssh与if条件结合?
我试过这个,但没有成功。
#!/bin/bash
ssh -t test@192.168.94.139 "cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
echo "deleted"
fi"
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
ls: 无法访问 *.tgz: 没有那个文件或目录
Sim*_*ler 11
是的,您可以通过以下方式执行复杂的脚本 ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ \$(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ \$(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
Run Code Online (Sandbox Code Playgroud)
此示例使用 bash here 文档来生成命令字符串。在任何情况下,通过 ssh 传递脚本都容易出错,因为引用和转义变量很困难(注意命令前的反斜杠)。如果脚本太复杂,最好通过复制它scp,然后在目标主机上执行它。
我没有尝试修复您的脚本,但这里有一个示例,说明如何在远程主机上进行计数和删除:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=(\$(find . -type f -name "*.tgz"))
if [[ \${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "\${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
Run Code Online (Sandbox Code Playgroud)
这ls -t *.tgz将不起作用,因为globbing只发生在本地系统上。同样ls用于计算文件也不是一个好主意,因为它还会返回像.,..和目录这样的条目。
注意:这里的问题实际上有两层。一个是“我想在可通过 SSH 访问的远程服务器上执行一项重要任务”。另一个是“我试图将一个复杂的字符串传递给一个命令,但该参数最终与我想要的不同。” 我在回答低级问题时没有讨论所使用的方法是否“正确”(方便、不易出错、安全等)来解决高级问题。正如其他答案和评论所示,它很可能不是。
你的命令行大部分是正确的;你只需要稍微改变一下引用。
主要问题是双引号字符串由您的本地 shell 扩展,因此这些$(...)部分将在您的本地系统上进行评估。要将它们传递给远程系统,您必须将脚本括在单引号中。
您还有一些嵌入式引号。在您的原始脚本中,有两个echos的参数;如果您将外部引号更改为单引号,它将是 awk 脚本。这些有效地导致引号被省略,这不会打扰echos,但它会弄乱 awk 脚本,因为大于号将成为输出重定向。因此,在将外部引号更改为单引号之后,请将它们更改为双引号。
这是您的脚本,引用已修复。脚本可能有其他问题,我只是修复了语法。
#!/bin/bash
ssh -t test@192.168.94.139 'cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk "NR >3"|xargs rm -f) ]
echo "deleted"
fi'
Run Code Online (Sandbox Code Playgroud)
我认为这整个复杂的引用内容足以证明不使用它而是使用脚本。如果您想避免多个
ssh连接,请将脚本通过管道传输到另一台主机,并让它在一个命令中运行:
本地文件,例如myscript.sh:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Run Code Online (Sandbox Code Playgroud)
然后:
cat myscript.sh | \
ssh -t test@192.168.94.139 \
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Run Code Online (Sandbox Code Playgroud)
或者(避免无用地使用 cat):
ssh -t test@192.168.94.139 \
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh" \
< myscript.sh
Run Code Online (Sandbox Code Playgroud)
这会将本地脚本通过管道传输myscript.sh到远程端,并在远程端将其重定向到(临时)文件/tmp/ms.sh、执行并最终删除。
注意:我没有检查原始脚本是否有错误,只是想展示这个想法。不需要容易出错的引用,并且脚本中的所有命令都在远程端执行。
| 归档时间: |
|
| 查看次数: |
13197 次 |
| 最近记录: |