Динамическое выполнение команд с помощью lftp — несколько команд

Я уверен, что есть простой способ сделать это, но я не нахожу его. Что я хочу сделать, так это выполнить серию команд, используя lftp, и я хочу избежать повторного подключения к серверу, если это возможно.

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

for f in "${myarray}"
do
cd $f;
nlist >> $f.txt;
cd ..;
done

Конечно, это не работает, но я должен представить, что есть простое решение того, чего я пытаюсь достичь.

Я совершенно неопытен, когда дело доходит до сценариев оболочки. Какие-либо предложения?


person dgo    schedule 30.08.2012    source источник


Ответы (1)


Сначала создайте строку, содержащую список команд lftp. Затем вызовите lftp, передав команду на его стандартный ввод. Сам Lftp может перенаправить вывод команды в файл с синтаксисом, напоминающим оболочку.

list_commands=""
for dir in "${myarray[@]}"; do
  list_commands="$list_commands
  cd \"$dir\"
  nlist >\"$dir.txt\"
  cd .."
done

lftp <<EOF
open -u $username,$password $site
$list_commands
bye
EOF

Обратите внимание, что я предполагаю, что имена каталогов не содержат обратную косую черту, одинарные кавычки или подстановочные символы. При необходимости добавьте правильное экранирование.

Кстати, чтобы прочитать строки из файла, см. -ifs-while-read/18936#18936">Почему так часто используется while IFS= read вместо IFS=; while read..?. Возможно, вы предпочтете совместить чтение из списка каталогов и построение команд:

list_commands=""
while IFS= read -r dir; do
  list_commands="$list_commands
  cd \"$dir\"
  nlist >\"$dir.txt\"
  cd .."
done <directory_list.txt
person Gilles 'SO- stop being evil'    schedule 30.08.2012
comment
Спасибо. Это именно то, что мне нужно. Были некоторые дополнительные сложности с окончанием строки, потому что я (я не упомянул об этом) работаю над окном Windows ---> В том, что вы написали, было только две вещи, которые, я думаю, могут быть неправильными (хотя это может быть потому, что окон). Я просто не мог заставить его работать с каталогами, в имени которых были пробелы - это не будет проблемой во время выполнения, но это запутало меня при тестировании. Кроме того, мне пришлось поставить двойные кавычки после знака =, где написано list_commands=$list_commands, чтобы заставить его работать. Определенно попал туда, куда мне было нужно. Благодарю вас! - person dgo; 31.08.2012
comment
@user1167442 user1167442 Отсутствующая двойная кавычка была опечаткой, исправлена. Если вы используете IFS=$'\r' instead of IFS=`, входной файл может иметь окончание строки Windows. Каталоги с пробелом должны работать (думаю, не проверял), что пошло не так? - person Gilles 'SO- stop being evil'; 31.08.2012
comment
Я пробовал несколько вариантов экранирования и снятия двойных кавычек вокруг переменной, например: cd \$dir\, но то, что произошло как на сервере, так и с выводом, было прочитано только как первая часть запроса - например, папка cd D интерпретировался как cd Folder D, и выходные данные будут в файлах Folder.txt и D.txt. Однако я не слишком беспокоюсь об этом, потому что во время выполнения он будет работать только с заглавными строками без пробелов, предварительно экранированными. Странно, однако. Я достаточно легко справился с проблемой windows \r с помощью tr -d \r. Очень кстати. - person dgo; 31.08.2012
comment
У меня еще не хватило выносливости, чтобы вникнуть в то время как IFS. Я проверю это, хотя. Спасибо за информативный ответ. - person dgo; 31.08.2012