I’m writing a script to remotely install linux software updates (which use a .bin updater tool) using Expect. I’m having trouble matching one block, and I’ve tried a bunch of variations with no success. I’ve gotten other similar scripts to work, but I’ve used wildcards to match newlines, and in this case, I need to make sure the list of files is exactly what I’m expecting, so I didn’t want to break it up with any wildcards that could hide a mismatch.
Can someone take a look and tell me what I’m doing wrong?
Console output, plain
Checking for local modifications.
List of modifications made within Jira directories.
The following provides a list of file modifications within the
atlassian-jira directory.
Modified files:
atlassian-jira/WEB-INF/classes/seraph-config.xml
bin/setenv.sh
conf/server.xml
Removed files:
(none)
Added files:
atlassian-jira/WEB-INF/classes/crowd.properties
[Enter]
My latest attempt to match it and send Enter (line breaks only added to Stack Overflow, not present in script
expect {*Checking for local modifications*Modified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]}
When I run through expect
with the -d
flag, this is what it prints:
expect: does "rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn" (spawn_id exp5) match glob pattern "*Checking for local modifications*Modified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]"? no
I’m running from an outer bash script like so:
#!/usr/bin/env bash
set -e
sudo expect -d << EOD
spawn ${INSTALLER_PATH}
expect_before timeout { exit 1 }
expect {Match phrase} {
send -- "r"
}
...
expect eof
EOD
** Update 4/5/2021 **
I tried @pynexj’s suggestion to use ""
instead of {}
to surround my expression (below), it still doesn’t work.
New script
sudo expect -d << EOD
...
expect "rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn" {
send -- "r"
}
expect eof
EOD
I ran the debug output I received through Beyond Compare and the two strings printed out match each other 100%.
Updated debug output
expect: does "rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn" (spawn_id exp5) match glob pattern "rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn"? no
Two strings on top of each other
You can scroll these sideways in Stack Overflow to see they match 100%:
# command output on top
rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn
rnnrnrnChecking for local modifications.rnrnList of modifications made within Jira directories.rnrnThe following provides a list of file modifications within thernatlassian-jira directory.rnrnModified files:rntatlassian-jira/WEB-INF/classes/seraph-config.xmlrntbin/setenv.shrntconf/server.xmlrnRemoved files:rnt(none)rnAdded files:rntatlassian-jira/WEB-INF/classes/crowd.propertiesrnrn[Enter]rn
# Expect expression underneath
2
Answers
I needed to make two changes to get it to match:
""
instead of{}
This is what I ended up with, making it as readable as possible:
In Tcl, backslash escaped strings (like
rn
) embedded in braces ({}
) has no special meaning. You should use double quotes here.According to Tcl doc:
But note that when you use double quotes. To match
[Enter]
you need to write\[Enetr\]
because by default theexpect
statement uses glob-style matching. For example:UPDATE:
Just noticed you are using Bash’s here doc. Then you have to do one more level quoting.
Or you can use
<< "QUOTED_STRING_HERE"
:According to
man bash
, for<< word
: