Как подключиться с помощью ssh по прямому соединению Ethernet? [Дубликат]

В вашем скрипте есть различные возможные точки отказа. Прежде всего, rm *.old* будет использовать globbing для создания списка всех совпадающих файлов и может иметь дело с именами файлов, содержащими пробельные символы. Однако ваш скрипт присваивает переменную каждому результату glob и делает это без кавычек. Это сломается, если ваши имена файлов содержат пробелы. Например:

$ ls
'file name with spaces.old.txt'  file.old.txt
$ rm *.old.*   ## works: both files are deleted

$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'

Как вы можете видеть, цикл не удался для файла с пробелами в его имени. Чтобы сделать это правильно, вам нужно указать следующую переменную:

$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'

То же самое относится к почти любому использованию $i в вашем скрипте. Вы должны globbing .

Следующая возможная проблема заключается в том, что вы, кажется, ожидаете, что *.old.* соответствует файлам с расширением .old. Это не так. Он соответствует «0 или более символов» (*), затем ., затем «старый», затем другой ., а затем «0 или более символов снова». Это означает, что он не будет соответствовать чему-то вроде file.old, но только что-то вроде `file.old.foo:

$ ls
file.old  file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo     

Итак, нет совпадающего foe file.old. В любом случае ваш скрипт намного сложнее, чем необходимо. Попробуйте это вместо:

#!/bin/bash

for i in *; do
    if [[ -f "$i" ]];  then
        if [[ "$i"  ==  *.old ]]; then
            rm -v "$i" || echo "rm failed for $i"
        else
            echo "$i doesn't have an .old extension"
        fi
        cp -v "$i" "$i".old
    else
        echo "$i is not a file"
    fi 
done

Обратите внимание, что я добавил -v в выражения rm и cp which does the same thing as what you were doing with your echo`.

Это не идеально, поскольку, когда вы обнаружите, например, file.old, это будет удалено, а позже скрипт попытается скопировать его и сбой, поскольку файл больше не существует. Однако вы не объяснили, что вы на самом деле пытаетесь сделать сценарий, я не могу исправить это для вас, если вы не сообщите нам, что вы на самом деле пытаетесь выполнить.

Если вы хотите: i) удалить все файлы с расширением .old и ii) добавить расширение .old в любые существующие файлы, которые его не имеют, все, что вам действительно нужно:

#!/bin/bash

for i in *.old; do
    if [[ -f "$i" ]]; then
        rm -v "$i" || echo "rm failed for $i"
    else
        echo "$i is not a file"
    fi 
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
    if [[ -f "$i" ]]; then
        ## the -v makes cp report copied files
        cp -v "$i" "$i".old
    fi
done

6
задан 11 February 2012 в 08:15

0 ответов

Другие вопросы по тегам:

Похожие вопросы: