Невозможно запустить локальный файл сценария с переменными через ssh

Мой собственный ответ, после изучения ответа и комментария автор icarus :
Вы должны различать «новую строку в файле» и «новую строку в консоли». В консоли истинным символом новой строки является CRLF, что противоречит интуиции, как мы увидим ниже.

В контексте UNIX в текстовых файлах LF означает перевод строки, и наоборот, вы подразумеваете перевод строки под LF. (Под «вы имеете в виду» я имею в виду текст на естественном языке.) В DOS CR + LF и так далее. Ok. Все это знают.

(Unix) консоль более сложная. Сначала вы должны помнить, что LF и CR являются управляющими кодами, т.е. могут использоваться для управления консолью, например выделение полужирным шрифтом, цветом и т. д.

Если вы введете LF (\ n, перевод строки) в консоль, вы получите новую строку. Уловка состоит в том, что два улова таковы: (1) консоли, так сказать, двухслойные; они состоят из фильтра и части рендеринга. (Специальная номенклатура.) Скрытый (для обычных пользователей) фильтр переводит LF в CRLF. (2) Средству визуализации нужен CRLF (\ r \ n) для новой строки в обычном смысле. Подробнее см. Ниже.

Машинописный файл, созданный командой script (1) , записывает символы после фильтрации ввода в консоль. Вот почему символы новой строки в машинописном тексте - это CRLF.

Подробности и разное. факты:

  • Консольный рендерер печатает LF как «переместить курсор на одну строку вниз» и CR как «переместить курсор в начало строки».
  • Вы можете отключить преобразование LF-> CRLF с помощью $ stty -opost и стереть его с помощью $ stty opost . "opost" - это аббревиатура от "POST-обработка вывода".
    • Точнее, opost выполняет LF-> LFCR, когда установлено onlcr . Когда установлено onocr , CR будет удален в начале строки и т. Д. Ссылка: POSIX, глава 11 « Общий интерфейс терминала ».
  • Клавиша «Enter» связана с LF в Unix, что называется «Return» в терминологии раскладки клавиатуры. (См. этот вопрос для подробностей.)
  • Также есть варианты escape-кода; man 4 console_codes объясняет, что «ESC D» (\ eD) означает перевод строки, а «ESC E» (\ eE) - перевод строки. Если вы их распечатаете, «ESC D» будет «перемещать курсор вниз», а «ESC E» - CR + LF, независимо от ± opost-ness.

Для экспериментов рекомендую писать с отдельной консоли. Например, $ echo -ne '1st \ n2nd \ r \ n3rd \ n "> / dev / tty1 записывает в первую консоль, отличную от X, а / dev / pts / 0 это первый X-терминал.Это не самый удобный способ, но и наименее неоднозначный.

1
18.11.2018, 08:41
2 ответа

Вы говорите оболочке на другом компьютере, что нужно использовать файл ./ variables , который отсутствует в pwd этой оболочки. Пошагово это выглядит так:

  1. Эта команда подключается через ssh и отправляет строки из локального test.sh

     ssh -i "auth.key" user @ host 'bash -s' < test.sh 
     
  2. Удаленные оболочки запускаются соединением ssh , а затем получают следующие строки:

    • #! / bin / bash Интерпретация этого строка удаленной оболочки зависит от того, что это за оболочка. Большинство командных интерпретаторов рассматривают эту строку как комментарий. Если оболочка - sh , удаленная оболочка не станет bash , потому что строка shebang действительна только в файлах сценария, а сценариям необходимо установить исполняемый бит.
    • source ./variables.txt Теперь удаленной оболочке указывается источник из файла variables.txt в текущем рабочем каталоге. Если файла нет, оболочка выдаст ошибку. В вашем случае оболочка - это Bash, и ошибка:

       bash: строка 2: ./variables.txt: нет такого файла или каталога 
       
    • echo $ name Потому что $ name пусто, в терминале печатается только пустая строка.

Чтобы убедиться в этом сами, поместите файл variables.txt в удаленный домашний каталог с другой строкой источника, скажем:

name=remotehost

И запустите свой тестовый скрипт, как раньше.

1
27.01.2020, 23:34

Программы, запущенные на удаленном компьютере, видят файлы на удаленном компьютере, а не файлы на компьютере, с которого вы запустили ssh . Вы говорите SSH скопировать содержимое test.sh на удаленный компьютер и передать его в качестве входных данных в bash там, поэтому у вас не возникнет проблем с запуском test.sh . Но когда сценарий (который bash получает на стандартный ввод) пытается прочитать variables.txt , он ищет его на машине, на которой он выполняется (это не так, как если бы у него был выбор), и не не найти.

Если ваш сценарий не слишком сложен и в нем нет вложенных включений, вы можете выполнить замену текста, чтобы встроить содержимое сценария. Обратите внимание, что это ненадежно - это работает только в том случае, если source ./variables.txt отображается непосредственно в скрипте, а не в том случае, если он включает сложные кавычки, переменные, eval и т. Д. Для простоты я Предположим, что команда source находится одна в своей строке. Для более сложных сценариев можно было бы справиться с более сложными преобразованиями.

<test.sh sed '/^[ \t]*source variables\.txt[ \t]*$/ {
  d
  r variables.txt
}' | ssh -i "auth.key" user@host 'bash -s'
1
27.01.2020, 23:34

Теги

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