Bash - Как найти все файлы НЕ в массиве

-o password_stdin , похоже, не работает на всех системах, например на freeBSD. и т.д.

Вы также можете использовать интерпретатор expect , он должен работать с sshfs и должен делать свое дело.

Другим решением может быть sshpass , например, допустим, вы выполняете резервное копирование каталога / var / www

Резервное копирование:

name=$(date '+%y-%m-%d')
mkdir /backup/$name && tar -czvf /backup/$name/"$name.tar.gz" /var/www

загрузка файла резервной копии на сервер резервного копирования

sshpass -p "your_password" scp -r backup_user@target_ip:/home/ /backup/$name

Так что он будет загрузить каталог с сегодняшней резервной копией

Но все же, как было сказано выше, лучшим (безопасным и простым) способом было бы использовать пару ключей ssh ​​
Единственное неудобство было бы, если бы вам нужно было пройти процесс генерации ключа один раз на каждом сервере, который вам нужно соединить, но это лучше, чем хранить пароль в текстовом формате на всех серверах, для которых вы хотите создать резервную копию :),

Генерация ключа Правильное соединение

  • На локальном сервере

     ssh-keygen -t rsa 
     
  • На удаленном сервере

     ssh root @ remote_servers_ip "mkdir -p.ssh "
     
  • Загрузка сгенерированных открытых ключей на удаленный сервер

     cat ~ / .ssh / id_rsa.pub | ssh root @ remote_servers_ip" cat >> ~ / .ssh / authorized_keys "{{1} } 
  • Установить разрешения на удаленном сервере

     ssh root @ remote_servers_ip "chmod 700 ~ / .ssh; chmod 640 ~ / .ssh / authorized_keys "
     
  • Login

     ssh root @ remote_servers_ip 
     
  • Включение протокола SSH v2

    раскомментируйте" Протокол 2 "в / etc / ssh / sshd_config

  • включение авторизации с открытым ключом в sshd

    раскомментируйте «PubkeyAuthentication yes» в / etc / ssh / sshd_config

  • Если для параметра StrictModes задано значение yes в / etc / ssh / sshd_config, тогда

     restorecon -Rv ~ /.ssh
    
1
28.03.2017, 23:46
4 ответа

Предположим, что у вас есть массив с именами файлов и вы хотите узнать, какие из них отсутствуют в каталоге, просто пройдитесь циклом по массиву и проверьте, существуют ли файлы. (-f проверяет обычные файлы, -e - файлы любого типа)

files=(file1 file2 file4)
for f in "${files[@]}" ; do 
    [ -f "$f" ] || echo "$f: not found"
done 

Обратный способ аналогичен, но требует двойного цикла или превращения массива в ассоциативный массив. С двойным циклом:

files=(file1 file2 file4)
for f in * ; do
        found=0
        for g in "${files[@]}" ; do
                [ "$f" = "$g" ] && found=1
        done
        [ "$found" = 0 ] && echo "$f: in directory but not listed"
done 
3
27.01.2020, 23:13
perl -le '-e or print for qw/file1 file2 file4/'
0
27.01.2020, 23:13

Для объединения и дизъюнкции массивов смотрите zsh вместо bash .

$ expected=(file1 file2 file4)
$ existing=(file1 file2 file3) # or existing=(file*) to use globbing

$ echo missing: ${expected:|existing}
missing: file4
$ echo found: ${expected:*existing}
found: file1 file2
$ echo unexpected: ${existing:|expected}
unexpected: file3

Мнемоника (по крайней мере, моя, я не знаю, официальные ли они):

  • $ {A: | B} : элементы $ A bar элементы $ B
  • $ {A: * B} : элементы $ A с элементами $ B .
4
27.01.2020, 23:13

Если вам нужно проверить кучу файлов, функция - лучшее решение. В противном случае достаточно простого ls файла! Ниже приведен результат, который вы получите, когда искомого файла нет:

../theDirIWantToCheck $ ls theFileIWantToFind.txt
ls: theFileIWantToFind.txt: No such file or directory

Я также рекомендовал бы использовать завершение табуляции. Введите команду ls , а затем начните вводить имя любого ожидаемого файла. Вам нужно всего лишь ввести несколько символов, а затем нажать табуляцию (если это не сработает, нажмите табуляцию дважды). Все имена файлов, соответствующие этому шаблону, будут представлены , если они существуют.

$ ls fi<tab>
file1.txt file2.txt file3.txt file_new.txt filetypes.txt

Вы также можете передать ls несколько аргументов для проверки нескольких файлов:

$ ls file1.txt file2.txt file3.txt
...

Если файлы используют один и тот же префикс шаблона (например, файл1, файл2, файл3), вы можете использовать расширение скобок. . Это похоже на передачу всех трех аргументов в сжатой форме. .. представляет собой диапазон.

$ ls file{1..3}.txt
ls: file1.txt: No such file or directory
ls: file2.txt: No such file or directory
ls: file3.txt: No such file or directory

В качестве альтернативы вы можете использовать подстановочный знак для передачи всех возможных подходящих шаблонов с общим префиксом «файл» (например, file1.txt, file_other.txt):

$ ls file*
...

Наконец, вы можете передать все аргументы в массиве на ls и пусть он печатает за вас, а не использует echo . Более того, если вы используете параметр -l для ls , когда файлы действительно существуют, вы можете получить некоторые дополнительные сведения о них, такие как разрешения, размер файла и последнее изменение. дата / время.

0
27.01.2020, 23:13

Теги

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