【问题标题】:Bash command to check if file exists doesn't work though the file name is matching尽管文件名匹配,但用于检查文件是否存在的 Bash 命令不起作用
【发布时间】:2019-04-09 18:28:24
【问题描述】:
我有以下脚本来连接到 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 上运行它。任何帮助将不胜感激。
【问题讨论】:
标签:
bash
shell
terminal
scripting
【解决方案1】:
您是否知道 if 语句在您的 Mac 上而不是在服务器上查找文件?
您是否想检查文件变量是否为空? if [[ -f "$file" ]]; then
【解决方案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.txt 和 ssh .... 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 连接会更快。