简体   繁体   English

Function 在此处调用 unix shell 脚本的文档

[英]Function calls in Here Document for unix shell script

I'm working on a shell script to move some files around.我正在使用 shell 脚本来移动一些文件。 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.该脚本需要能够在本地计算机或远程服务器上操作文件,具体取决于传入的 arguments。我已经设法组合了一个简单的 function 来满足我的需求。 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.我似乎无法弄清楚如何在 Here 文档中使用该 function 以便它可以在远程服务器上执行。 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.我在这里发现了一个类似的问题: 从 shell 脚本中,我们可以从这里的文档中调用 function但是给定的答案对我不起作用。

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 ./myscript.sh 远程开发

I get an output like:我得到一个 output 像:

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.查看 output,它似乎正试图将 output 作为命令从“echo”和“ls”调用传递到 /bin/bash,而不是将它们打印到控制台。 While this is a contrived example, I would like to be able to have logging statements inside my function that print to stdout.虽然这是一个人为的例子,但我希望能够在我的 function 中包含打印到标准输出的日志语句。 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. ${param@Q}形式将 value 扩展为引用版本,允许安全地重新评估作为参数。 It's a Bash feature that became available starting 4.4.这是从 4.4 开始提供的 Bash 功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM