虽然文件名匹配,但Bash命令无法检查文件是否存在

时间:2018-11-06 11:04:34

标签: bash shell terminal scripting

我有以下脚本连接到SFTP服务器并删除与名称匹配的文件。但是,尽管服务器中存在具有匹配名称的文件,但脚本无法进入-f检查块,因此无法删除该文件。我在这里做错了什么?下面是我的脚本。

readarray partners < fileName.txt

for i in "${partners[@]}"
do
  file=`echo "ls" | sftp -i myKey myUser@myIP:${i} | grep "_Name_file_20181024"`
  echo $i
  echo $file

  if [[ -f $file ]]; then
    echo "********"
    delete=`echo "rm $file" | sftp -i myKey myUser@myIP:${i}`
    echo "********"
    echo $delete
  fi


done

我正在Mac上运行它。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

-f检查文件您的计算机上是否存在
我想您可以检查文件字符串是否为非空:

if [ -n "$file" ]; then

但是更希望检查grep的结果:

if echo "ls" | sftp -i myKey "myUser@myIP:$i" | grep -q "_Name_file_20181024"; then

其余:

  • 反引号`已弃用。使用$( ... )进行命令替换,从而可以嵌套(并且更具可读性)。
  • 始终引用变量。如果文件名带有空格怎么办?
  • sftp仅为ssh,但仅文件传输。
  • 不解析ls输出。这不好。 ls用于获得格式良好的输出。

我会这样一遍:

<fileName.txt xargs ssh -i myKey "myUser@myIP" rm -v -f

xargs将把fileName.txt中的每一行转换为单独的参数。或者,如果您没有xargs,则可以readarray partners < fileName.txtssh .... rm -v -f "${partners[@]}"ssh将运行一次(因此非常快)。如果仅检查文件是否存在然后删除,那么最终结果是否不存在,为什么还要检查?如果删除的文件不存在,-f选项将使rm不会失败;如果删除了文件,则-v将打印(因此您将知道删除了哪些文件)。

或者如果您必须sftp,这可能会起作用:

echo "rm -v -f $(<fileName.txt xargs printf "%q ")" |
sftp -i myKey myUser@myIP

但是我不确定文件名中的特殊字符,因此我认为这需要进行一些调整。

如果您要从列表中过滤不存在​​的文件,我会这样做:

<fileName.txt ssh -i myKey "myUser@myIP" 'while IFS= read -r file; do [ -f "$file" ] && echo "$file"; done' 

即。 while IFS= read -r部分是远程执行的,因此检查文件在删除服务器上是否存在。执行所有工作的单个ssh连接,然后对单个文件执行单独的ssh连接,速度更快。

答案 1 :(得分:1)

您是否知道if语句在Mac而不是服务器上查找文件?

您可能要检查文件变量是否为空? if [[ -f "$file" ]]; then