I am trying to work around a situation where I need to login to a multitude of servers without being able to utilize ssh keys. As a result I am formulating a "that is a bad practice"-expect script:
#!/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
Running it works fine:
$ ./ssh.expect server
spawn ssh server -l user hostname; env x='() { :;}; echo vulnerable' bash -c "echo this is a test"; echo
user@server's password:
server
this is a test
$
But I need a better formatted list when running on more than one system, so I attempt to let perl reformat the data:
$ ./ssh.expect server | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1:$line2\n";'
:this is a test
The server name is printed as if it ends with a \r. I don't think that it should. Do you agree? How can I get the system to not return to column 0 after printing the server name?
I can verify that both variables contain data by adding a newline to my print:
$ ./ssh.expect server | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1\n:$line2\n";'
server
:this is a test
EDIT:
As commented, the following works.
./ssh.expect server | tr -d '\r' | perl -e '$dump = <>; $dump = <>; chomp($line1 = <>); chomp($line2 = <>); $dump = <>; print "$line1:$line2\n";'
server:this is a test
Shouldn't chomp make the tr redundant?
Expect uses a pseudo-TTY to communicate with the command that it spawns, which in this case is the ssh process. TTYs and PTYs by default will translate \n to \r\n (LF to CRLF) in output text. So the output of your expect script would contain CRLF sequences unless you took the effort to remove the CR's. You can see this by running expect
interactively:
$ 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 LF->CRLF conversion is controlled by the TTY "onlcr" flag. I played around with turning that flag off in the expect script but wasn't successful.
Perl's chomp
command removes sequences of the perl input record separator (the $/
variable), which will just be \n on Unix systems. In other words, \r isn't special to chomp
on unix by default. You could alter $/
in your perl script to make chomp remove the carriage returns, if you like. Or you could pipe the output of your expect script through tr
, as discussed.