Here Document for unix shell 脚本中的函数调用
Function calls in Here Document for unix shell script
我正在编写 shell 脚本来移动一些文件。该脚本需要能够根据传入的参数对本地计算机或远程服务器上的文件进行操作。我已经设法组合了一个简单的函数来执行我想要的操作。我似乎无法弄清楚的是如何在 Here 文档中使用该功能,以便它可以在远程服务器上执行。我在这里发现了一个类似的问题:From shell script can we invoke function from here document 但给出的答案对我不起作用。
这是我到目前为止的想法:
myscript.sh
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
doMove()
{
echo "$JETTY_BASE/webapps/eyerep-data/"
sudo touch $JETTY_BASE/webapps/eyerep-data//myfile
ls $JETTY_BASE/webapps/eyerep-data/;
}
moveRemote()
{
echo "attempting move with here doc"
ssh -t $REMOTE_HOST "/bin/bash <<EOF
$(doMove )
EOF"
}
moveFiles()
{
case "" in
# remote deploy
remote)
moveRemote
;;
# local deploy
local)
doMove
;;
*)
echo "Usage: myscript.sh {local|remote}"
exit 1
;;
esac
}
如果我运行上面有
./myscript.sh remote dev
我得到如下输出:
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
查看输出,它似乎试图将 'echo' 和 'ls' 调用的输出作为命令传递给 /bin/bash,而不是将它们打印到控制台。虽然这是一个人为的例子,但我希望能够在我的函数中包含打印到标准输出的日志语句。处理此问题的最佳方法是什么?
试试这个:
#!/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 ""
eval "$__"
}
moveRemote() {
echo "Attempting move with here doc"
generateMoveCommands ""
ssh -t "$REMOTE_HOST" "$__"
}
showUsage() {
echo "Usage: [=10=] {local|remote} file"
exit 1
}
main() {
case in
# remote deploy
remote)
[[ ]] || showUsage
moveRemote ""
;;
# local deploy
local)
[[ ]] || showUsage
moveLocal ""
;;
*)
showUsage
;;
esac
}
main "$@"
形式 ${param@Q}
将值扩展为引用版本,允许作为参数安全地重新计算。这是从 4.4 开始可用的 Bash 功能。
备选方案:
#!/bin/bash
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
doMove() {
local jetty_base= file=
echo "${jetty_base}/webapps/eyerep-data/${file}"
sudo touch "${jetty_base}/webapps/eyerep-data/${file}/myfile"
ls "${jetty_base}/webapps/eyerep-data/${file}"
}
moveRemote() {
echo "Attempting move with here doc"
ssh -t "$REMOTE_HOST" "$(declare -fp doMove)"$'\n'"doMove ${JETTY_BASE@Q} ${1@Q}"
}
showUsage() {
echo "Usage: [=11=] {local|remote} file"
exit 1
}
main() {
case in
# remote deploy
remote)
[[ ]] || showUsage
moveRemote ""
;;
# local deploy
local)
[[ ]] || showUsage
doMove "$JETTY_BASE" ""
;;
*)
showUsage
;;
esac
}
main "$@"
我正在编写 shell 脚本来移动一些文件。该脚本需要能够根据传入的参数对本地计算机或远程服务器上的文件进行操作。我已经设法组合了一个简单的函数来执行我想要的操作。我似乎无法弄清楚的是如何在 Here 文档中使用该功能,以便它可以在远程服务器上执行。我在这里发现了一个类似的问题:From shell script can we invoke function from here document 但给出的答案对我不起作用。
这是我到目前为止的想法:
myscript.sh
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
doMove()
{
echo "$JETTY_BASE/webapps/eyerep-data/"
sudo touch $JETTY_BASE/webapps/eyerep-data//myfile
ls $JETTY_BASE/webapps/eyerep-data/;
}
moveRemote()
{
echo "attempting move with here doc"
ssh -t $REMOTE_HOST "/bin/bash <<EOF
$(doMove )
EOF"
}
moveFiles()
{
case "" in
# remote deploy
remote)
moveRemote
;;
# local deploy
local)
doMove
;;
*)
echo "Usage: myscript.sh {local|remote}"
exit 1
;;
esac
}
如果我运行上面有
./myscript.sh remote dev
我得到如下输出:
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
查看输出,它似乎试图将 'echo' 和 'ls' 调用的输出作为命令传递给 /bin/bash,而不是将它们打印到控制台。虽然这是一个人为的例子,但我希望能够在我的函数中包含打印到标准输出的日志语句。处理此问题的最佳方法是什么?
试试这个:
#!/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 ""
eval "$__"
}
moveRemote() {
echo "Attempting move with here doc"
generateMoveCommands ""
ssh -t "$REMOTE_HOST" "$__"
}
showUsage() {
echo "Usage: [=10=] {local|remote} file"
exit 1
}
main() {
case in
# remote deploy
remote)
[[ ]] || showUsage
moveRemote ""
;;
# local deploy
local)
[[ ]] || showUsage
moveLocal ""
;;
*)
showUsage
;;
esac
}
main "$@"
形式 ${param@Q}
将值扩展为引用版本,允许作为参数安全地重新计算。这是从 4.4 开始可用的 Bash 功能。
备选方案:
#!/bin/bash
REMOTE_HOST=myserver
JETTY_BASE=/opt/web/jetty
doMove() {
local jetty_base= file=
echo "${jetty_base}/webapps/eyerep-data/${file}"
sudo touch "${jetty_base}/webapps/eyerep-data/${file}/myfile"
ls "${jetty_base}/webapps/eyerep-data/${file}"
}
moveRemote() {
echo "Attempting move with here doc"
ssh -t "$REMOTE_HOST" "$(declare -fp doMove)"$'\n'"doMove ${JETTY_BASE@Q} ${1@Q}"
}
showUsage() {
echo "Usage: [=11=] {local|remote} file"
exit 1
}
main() {
case in
# remote deploy
remote)
[[ ]] || showUsage
moveRemote ""
;;
# local deploy
local)
[[ ]] || showUsage
doMove "$JETTY_BASE" ""
;;
*)
showUsage
;;
esac
}
main "$@"