2014-12-17 5 views
4

Я пытаюсь обойти ситуацию, когда мне нужно зайти на сервер , не имея возможности использовать ключи ssh. В результате я формулируя «который является плохой практикой» -expect сценарий:Откуда берутся?

#!/usr/bin/expect 
set arg1 [lindex $argv 0] 
spawn ssh $arg1 -l user "hostname; env x='() { :;}; echo vulnerable' bash -c \"echo this is a test\"; echo" 
expect " password:" 
send "my_supersecret_password\n" 
interact 

Бег это работает отлично:

$ ./ssh.expect server 
spawn ssh server -l user hostname; env x='() { :;}; echo vulnerable' bash -c "echo this is a test"; echo 
[email protected]'s password: 
server 
this is a test 

$ 

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

$ ./ssh.expect server | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1:$line2\n";' 
:this is a test 

имя сервера печатается как, если он заканчивается \ г. Я не думаю, что так и должно быть. Вы согласны? Как я могу заставить систему не возвращаться к столбцу 0 после печати имени сервера?

Я могу подтвердить, что обе переменные содержат данные, путем добавления новой строки в моей печати:

$ ./ssh.expect server | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1\n:$line2\n";' 
server 
:this is a test 

EDIT:

Как отметил следующие работы.

./ssh.expect server | tr -d '\r' | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1:$line2\n";' 
server:this is a test 

Не следует ли помнить tr trundundant?

+1

Обычно это происходит из окон, связанных с окнами. до 'tr -d '\ r'' до вашей команды perl. – arco444

+0

Как глупо, это работает как шарм! Я просмотрел вывод в vim, но в списке нет \ r, поэтому я даже не пытался его обрезать. – azzid

+1

'\ r' is'^M' в vim, но vim достаточно умен, чтобы понимать файлы новой строки DOS и скрывать их (т. Е. Вы будете видеть их только в смешанных файлах окончания строки). –

ответ

2

Ожидание использует псевдоТТЮ для связи с командой, которую он порождает, что в данном случае является процессом ssh. TTY и PTY по умолчанию преобразуют \ n в \ r \ n (LF в CRLF) в выходной текст. Таким образом, вывод вашего сценария ожидания будет содержать последовательности CRLF, если вы не предпримете усилий для удаления CR. Вы можете увидеть это, запустив expect интерактивно:

$ expect -c 'spawn echo foo; interact' | od -a 
0000000 s p a w n sp e c h o sp f o o cr nl 
0000020 f o o cr nl            
0000025    ^^--^^--note 

TTY НЧ-> преобразование CRLF управляется TTY "ONLCR" флаг. Я играл с выключенным флагом в сценарии ожидания, но не был успешным.

Команда Perl's chomp удаляет последовательности разделителя входных записей perl (переменная $/), которая будет просто \ n в системах Unix. Другими словами, \ r не является особым для chomp по unix по умолчанию. Вы можете изменить $/ в своем скрипте perl, чтобы chomp удалил возврат каретки, если хотите.Или вы можете передать вывод своего сценария ожидания через tr, как обсуждалось.

0

\r используется терминалами; клавиша Enter на вашей клавиатуре фактически отправляет \r, а ядро ​​Linux переводит ее на \n; \r\n - это строка, заканчивающаяся выходом на терминал, а ядро ​​Linux переводит \n на выход. Можно отключить эти переводы, поставив терминал в «сырой режим», в котором программа может напрямую разговаривать с терминалом (см. http://www.linusakesson.net/programming/tty/). Это необходимо для программ полноэкранных, такие как vi, nethack и т.д.

Я думаю, что ssh ставит терминал в нестандартный режим на клиенте (ваш конец), поэтому ядро ​​на стороне сервера может сделать \n ->\r\n перевод на мощность. Это то, что позволяет вам запускать vi под ssh, но это означает, что при запуске ssh под программой нужно притворяться терминалом, что означает отправку \r как EOL на выходе и чтение \r\n как EOL на входе.

 Смежные вопросы

  • Нет связанных вопросов^_^