expect command variable with pipes and special characters not working
Use lindex
instead of lrange
:
#!/usr/bin/expect -f
set password [lindex $argv 0]
set ipaddr [lindex $argv 1]
set command [lindex $argv 2]
... ...
send -- "$command\r"
And call your script this way:
./myexpectscript password ip "echo hello world"
expect in bash script with special characters 2 parts
In your last line block, try manually adding a \ before each special character that needs to be escaped. That shouldn't be much work.
Also, use == for the equality check, i.e.:
echo -n $pass | while read -n 1 c; do [[ "$c" == [!@#$%^&*().] ]] && echo -n "\\"; echo -n $c; done
What characters should be escaped in Expect, and how?
The way you're declaring your expect script, in a double quoted string in the shell, is the main source of your pain. If you don't rely on interpolating shell variables, you can use a single-quoted here-doc:
setup_multicraft=$(expect <<'END_OF_EXPECT'
set timeout 10
spawn ./setup.sh
expect {Run each Minecraft server under its own user? (Multicraft will create system users): [y]/n}
send "y\r"
# ...
END_OF_EXPECT
)
Much tidier, no?
In Tcl (and expect) command substitution is done in square brackets (equivalent to shell backticks), so if you want to use brackets in a double quoted string, they need to be escaped.
In Tcl, you can use curly braces to prevent variable expansion and command substitution (equivalent to shell single quotes). I've demonstrated that here.
The entire syntax of Tcl is described here. You would benefit from a quick run-through of the Tcl tutorial.
expect output only stdout of the command and nothing else
Capturing the output from sent commands is a bit of a pain in expect.
Here's a more general case that does not rely on the log_user setting, it captures the output with a regular expression:
#!/usr/bin/expect
log_user 0
spawn bash
# set the prompt to a known value
send "PS1='>'\r"
expect -re {>$}
# send a command: we don't know what the output is going to be
send "echo \$RANDOM\r"
# capture the portion of the output that occurs just before the prompt
expect -re "\r\n(.*?)\r\n>$"
puts "output is: $expect_out(1,string)"
send "exit\r"
expect eof
A thought just occurred to me: if the command does not require any interaction, then expect is overkill: just use exec
set output [exec bash -c {echo $RANDOM}]
Tcl / Expect script driven by name pipe blocks/buffers output unexpectedly
According to fifo(7):
Normally, opening the FIFO blocks until the other end is opened also.
So, in the proc read_command
, it's blocking on set cpipe [open "$::env(CMDPIPE)" r]
and does not get the chance to display the spawned process's output until you echo ... >> ${CMDPIPE}
again.
To work it around, you can open the FIFO (named pipe) in non-blocking mode:
set cpipe [open "$::env(CMDPIPE)" {RDONLY NONBLOCK} ]
This is also mentioned in fifo(7):
A process can open a FIFO in nonblocking mode. In this case, opening for read-only will succeed even if no one has opened on the write side yet ...
The following is the simplified version of your code and it works fine for me (tested on Debian 9.6).
spawn bash --norc
set timeout -1
expect -re {bash-[.0-9]+[#$] $}
send "PS1='P''rompt: '\r"
# ^^^^
expect "Prompt: "
proc do { cmd } {
send "$cmd\r"
if { $cmd == "exit" } {
expect eof
exit
} else {
expect "Prompt: "
}
}
proc read_command {} {
global cpipe
if {[gets $cpipe cmd] < 0} {
close $cpipe
set cpipe [open cpipe {RDONLY NONBLOCK} ]
fileevent $cpipe readable read_command
} else {
do $cmd
}
}
set cpipe [open cpipe {RDONLY NONBLOCK} ]
fileevent $cpipe readable read_command
vwait forever
Related Topics
Linux Kernel Headers' Organization
How to Install a Node.Js Server at Chat.Mydomain.Com on a Hostgator Vps Hosting
Identifying the Preferred Ipv6 Source Address for an Adapter
How to Change Alignment of Code Segment in Elf
The New Line Characted in the String Constant Isn't Being Recognized by Nasm
Total Number of Lines in a Directory
Unterminated Address Regex While Using Sed
How to Use a Linux Expect Script to Enter Answer a Prompt for Password
Making 'Long' 4 Bytes in Gcc on a 64-Bit Linux MAChine
How to Find the Count of Multiple Words in a Text File
How to Measure the Stack Size of a Process
Nacl Helper Process Running Without a Sandbox Error Using Chrome Through Selenium in Linux
Npm Install Causes Errors Like Npm Err! Tar.Unpack Untar Error on Debian
Cannot Open Libmpfr.So.4 After Update on Ubuntu 18.04
Explanation of Memcpy Memmove Glibc_2.14/2.2.5
Shell Script for Process Monitoring
How to Create a Zip File Without Entire Directory Structure
Bash Completion for Path in Argument (With Equals Sign Present)