Вывод имени удаленного хоста в сеансе sshpass

Спецификация POSIX дает вам пример для этого:

ls | sed -e 's/"/"\\""/g' -e 's/.*/"&"/' | xargs -E '' printf '<%s>\n'

(с именами файлов, представляющими собой произвольные последовательности из байтов (, отличных от /и NULL )и sed/ xargs, ожидающих текста , вам также необходимо исправить локаль на C (, где все не -байты NUL будут действительными символами ), чтобы сделать это надежным (, за исключением xargsреализаций, которые имеют очень низкий предел максимальной длины аргумента ))

. ]

-E ''необходим для некоторых xargsреализаций, которые без него понимали бы аргумент _для обозначения конца ввода (, где echo a _ b | xargsвыводит aтолько для примера ).

С GNU xargsвы можете использовать:

ls | xargs -d '\n' printf '<%s>\n'

GNU xargsтакже имеет -0, который был скопирован несколькими другими реализациями, поэтому:

ls | tr '\n' '\0' | xargs -0 printf '<%s>\n'

немного более портативный.

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

a
b

Это могут быть либо два файла aи b, либо файл с именем ab, точно сказать невозможно.

GNU lsимеет --quoting-style=shell-always, который делает его вывод однозначным и может обрабатываться после -, но цитирование несовместимо с цитированием, ожидаемым xargs. xargsраспознают "...", \xи '...'формы цитирования. Но и "...", и '...'являются сильными кавычками и не могут содержать символы новой строки. (только \может экранировать символы новой строки для xargs),так что это несовместимо с цитированием sh, где только '...'являются сильными кавычками (и могут содержать символы новой строки ), но \является продолжением строки -(удаляется )вместо экранированной новой строки.

Вы можете использовать оболочку для разбора этого вывода, а затем вывести его в формате, ожидаемомxargs:

eval "files=($(ls --quoting-style=shell-always))"
[ "${#files[#]}" -eq 0 ] || printf '%s\0' "${files[@]}" |
  xargs -0 printf '<%s>\n'

0
26.09.2019, 21:31
1 ответ

Вам необходимо экранировать $перед $HOSTNAMEпеременной (или командой $(hostname)), чтобы она разворачивалась/запускалась на удаленной машине, а не на локальной:

#!/bin/bash
while read PASSWORD SERVER;do
  sshpass -p "$PASSWORD" ssh -t -p 1234 $SERVER << EOF
    wget -N https://example.com/file.conf 2>&1 | grep -i "failed\|error\|saved"
    sed -i "s/variabletoreplace/\$HOSTNAME/" file.conf
  EOF
done

Как упоминалось в комментариях, было бы намного лучше использовать ключи ssh, а не sshpass, и если бы все эти команды, которые вы хотите запустить, находились в сценарии на удаленном хосте, это было бы намного проще. В качестве альтернативы может быть более подходящим использование такого инструмента, как ansibleили puppet.

0
28.01.2020, 03:15

Теги

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