Функция Bash работает только при ручном вводе пароля

603
N Klosterman

На работе мне приходится каждый день запускать следующую функцию. Функция работает нормально, когда мне предлагают пароль. Однако я попытался жестко закодировать свой пароль, чтобы не вводить его каждый день. Это не работает Любые намеки на то, почему?

function update() { firewalluser=`whoami` # -s => silent (no echo of characters), -p => prompt user #read -s -p "Password: " firewallpass  firewallpass="mypassword"  TRUSTED=( xxx.yyy.com jenkins.xxx.com svn.xxx.com ) for server in $ do echo "" echo "--> connecting to $server" expect <<EOF  set timeout 20  spawn telnet $server  expect "Username: "  send "$firewalluser\r"  expect "Password: "  send "$firewallpass\r"  expect "Firewall User Authentication: Accepted"  send "exit"  exit  EOF  done } 

Я запускаю это GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)с функцией, определенной в моем .bash_profile.

Заранее спасибо.

РЕДАКТИРОВАТЬ: я добавил, exp_internal 1и вот ответ от программы:

--> connecting to some.domain.name.com spawn telnet some.domain.name.com parent: waiting for sync byte parent: telling child to go ahead parent: now unsynchronized from child spawn: returns   expect: does "" (spawn_id exp7) match glob pattern "Username: "? no Trying xx.yy.zz...  expect: does "Trying xx.yy.zz...\r\n" (spawn_id exp7) match glob pattern "Username: "? no Connected to some.domain.name.com. Escape character is '^]'.  expect: does "Trying xx.yy.zz...\r\nConnected to some.domain.name.com.\r\nEscape character is '^]'.\r\n" (spawn_id exp7) match glob pattern "Username: "? no Please Authenticate to VSD DR2 Username: expect: does "Trying xx.yy.zz...\r\nConnected to some.domain.name.com.\r\nEscape character is '^]'.\r\nPlease Authenticate to VSD DR2\r\nUsername: " (spawn_id exp7) match glob pa\ tern "Username: "? yes expect: set expect_out(0,string) "Username: " expect: set expect_out(spawn_id) "exp7" expect: set expect_out(buffer) "Trying xx.yy.zz...\r\nConnected to some.domain.name.com.\r\nEscape character is '^]'.\r\nPlease Authenticate to VSD DR2\r\nUsername: " send: sending "nklosterman\r" to { exp7 }  expect: does "" (spawn_id exp7) match glob pattern "Password: "? no  Password: expect: does "\r\nPassword: " (spawn_id exp7) match glob pattern "Password: "? yes expect: set expect_out(0,string) "Password: " expect: set expect_out(spawn_id) "exp7" expect: set expect_out(buffer) "\r\nPassword: " send: sending "mypassword!\r" to { exp7 }  expect: does "" (spawn_id exp7) match glob pattern "Firewall User Authentication: Accepted"? no  Firewall User Authentication: Failed  expect: does "\nFirewall User Authentication: Failed\r\n" (spawn_id exp7) match glob pattern "Firewall User Authentication: Accepted"? no Connection closed by foreign host.  expect: does "\nFirewall User Authentication: Failed\r\nConnection closed by foreign host.\r\n" (spawn_id exp7) match glob pattern "Firewall User Authentication: Accepted"? no expect: read eof expect: set expect_out(spawn_id) "exp7" expect: set expect_out(buffer) "\nFirewall User Authentication: Failed\r\nConnection closed by foreign host.\r\n" send: sending "exit" to { exp7 send: spawn id exp7 not open while executing "send "exit"" 

Я вижу, что мой пароль отправляется с добавленным к нему символом \ r. Я не уверен, почему он не принимает это. Я даже пытался жестко закодировать свой пароль в heredoc вместо установки переменной, и это не сработало.

0
Обычно запросы паролей не проходят через стандартный ввод / вывод, поэтому ввод не может быть перенаправлен, а команды типа `echo password | su` не работают. Я не знаю программу «ожидаем», но похоже, что она работает, читая и записывая диалоги других программ, перенаправляя их ввод / вывод через каналы. В `ftp` вы можете поместить пароли (в виде обычного текста!) В файл инициализации` .netrc`, и я успешно автоматизирую FTP-передачу, используя это, но я не знаю, что `.telnetrc` позволяет то же самое. AFH 9 лет назад 0
Проблема, как представляется, связана с «ожидаем», из того, что я прочитал, должно быть возможно использовать пароли таким образом. И доволен ли ИТ-отдел вашей работы тем, что пароли хранятся в виде простого текста? Xen2050 9 лет назад 0
добавить `exp_internal 1` к ожидаемому сценарию до` set timeout`. Это включит многословную отладку, чтобы вы могли видеть, что ожидают делать с паролем. glenn jackman 9 лет назад 0
@ Xen2050 Что касается аспекта безопасности, я согласен, что это серьезная проблема безопасности. Тем не менее, это место назначает пароли и использует их (!) Так, что коллеги могут легко угадать ваш пароль. Поэтому я думаю, что открытый текст в скрипте - это наименьшее количество дыр, о которых стоит беспокоиться! N Klosterman 9 лет назад 0
Вы уверены, что вам нужно добавить `\ r` в` send "$ firewalluser \ r" `и` send "$ firewallpassword \ r" `? В других примерах я видел только `send" $ user "` ... Hastur 9 лет назад 0

1 ответ на вопрос

0
user210584

It look like a carriage return vs newline issue.

Your active terminal might not be matching the remote system and some automatic translation might be wrong. You can compare both system using the stty(1) command.

From the Expect documentation:

In this case, when you press return, it will be translated to a newline. If Expect then passes that to a program which sets its terminal to raw mode (like telnet), there is going to be a problem, as the program expects a true return.

Rather than manually replacing newlines with returns, the solution is to use the command "stty raw", which will stop the translation. Note, however, that this means that you will no longer get the cooked line-editing features.

I suggest you try replacing the \r with \n in your code. If that still doesn't work, it might need both \r\n to work. If it still doesn't work you'll have to troubleshoot the terminal mode of both system and what happen to the carriage returns and newlines as they go back and forth.

Also, this assume you have the right passwords of course! ;)