I'm working on a shell script to move some files around. This script needs to be able to operate on files either on a local machine or on a remote server depending on the arguments passed in. I have managed to put together a simple function that does what I want. What I can't seem to figure out is how to use that function in a Here document so it can be executed on the remote server. I found a similar question here: From shell script can we invoke function from here document but the given answers don't work for me.
Here is what I have come up with so far:
myscript.sh
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
doMove()
{
echo "$JETTY_BASE/webapps/eyerep-data/$1"
sudo touch $JETTY_BASE/webapps/eyerep-data/$1/myfile
ls $JETTY_BASE/webapps/eyerep-data/$1;
}
moveRemote()
{
echo "attempting move with here doc"
ssh -t $REMOTE_HOST "/bin/bash <<EOF
$(doMove $1)
EOF"
}
moveFiles()
{
case "$1" in
# remote deploy
remote)
moveRemote $2
;;
# local deploy
local)
doMove $2
;;
*)
echo "Usage: myscript.sh {local|remote}"
exit 1
;;
esac
}
If I run the above with
./myscript.sh remote dev
I get an output like:
attempting move with here doc
/bin/bash: line 1: /opt/web/jetty/webapps/eyerep-data/: Is a directory
/bin/bash: line 2: dev: command not found
/bin/bash: line 3: eyerep-data-dev.xml: command not found
/bin/bash: line 4: eyerep-data-local.xml: command not found
/bin/bash: line 5: local: can only be used in a function
Looking at the output, it looks like it is trying to pass the output from the 'echo' and 'ls' calls to /bin/bash as commands instead of printing them to the console. While this is a contrived example, I would like to be able to have logging statements inside my function that print to stdout. What is the best way to deal with this?
Try this one:
#!/bin/bash
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
generateMoveCommands() {
__="echo ${JETTY_BASE@Q}/webapps/eyerep-data/${1@Q}
sudo touch ${JETTY_BASE@Q}/webapps/eyerep-data/${1@Q}/myfile
ls ${JETTY_BASE@Q}/webapps/eyerep-data/${1@Q}"
}
moveLocal() {
generateMoveCommands "$1"
eval "$__"
}
moveRemote() {
echo "Attempting move with here doc"
generateMoveCommands "$1"
printf '%s\n' "$__" | ssh -t "$REMOTE_HOST" /bin/bash
}
showUsage() {
echo "Usage: $0 {local|remote} file"
exit 1
}
main() {
case $1 in
# remote deploy
remote)
[[ $2 ]] || showUsage
moveRemote "$2"
;;
# local deploy
local)
[[ $2 ]] || showUsage
moveLocal "$2"
;;
*)
showUsage
;;
esac
}
main "$@"
The form ${param@Q}
expands value to a quoted version which allows to be safely re-evaluated as an argument. It's a Bash feature that became available starting 4.4.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.