首页 > 解决方案 > 寻找一种在 ssh 命令中调用函数的行之有效的方法(ssh 是在函数之外编写的)

问题描述

我不是 shell 脚本方面的专家,但我编写了一个代码来根据一些唯一 ID 的用户输入来获取服务器日志。我的脚本结构如下所示:

function liveLogs(){

here -> logic to "read a .properties file line by line that contains all the directories to be searched"
grep the userinput ID in all directories

}

还有一个类似上面的函数 archiveLogs() 来搜索归档日志。

我在同一脚本中的主块中调用上述函数,如下所示:

if [[ $1 == "ARCHIVE" ]]
then
ARCHIVE="archiveLogs" --> assigning function to varibale
else
LIVE="liveLogs" --> assigning function to varibale

OutputLogFilePath = "a/Logfile.txt"

if [[ ! -z ${LIVE} ]]

ssh -q -T username@host "bash -s -- $ID" < ${LIVE} 2>&1 | tee -a ${OutputLogFilePath}
else 
ssh -q -T username@host "bash -s -- $ID" < ${ARCHIVE} 2>&1 | tee -a ${OutputLogFilePath}
fi

对于上述 ssh 命令,在终端上它会抛出 --> "no such file for directory"

根据我的研发,提到我们不能直接在远程主机上调用函数。我尝试了其他一些命令,例如

- declare -f
typeset -f
<<-EOF typeset-f funcname EOF
export -f fucntion and parallel --env

但没有什么对我有用。有人可以在这里帮忙吗?


以下是修改后的帖子以获取更多详细信息。
这是我要开始工作的主要部分。
从“如果”到“完成”的所有内容都是主要的块代码。

if [[ $1 == "HIST" ]]  
then  

    ARCHIVE="archiveLogs"
else  

    LIVE="liveLogs"

showmenus --> #function to display selection menu on terminal  
readoptions  --> #readoptions is a function with two cases to read unique ID as user input (Single input and multiple inputs)    

read userinput  
SERVERLIST="$userinput"  

while read -r line  

    do
        SERVERLIST=${line}
        
        if [[ ! -z ${LIVE} ]]
        then
        echo ${ARCHIVE}
        #changes I did to ssh as per your comments. Did'nt think of need for fucntion some_entrypoint()
        ssh -q -T fircoadm@${line} "bash -s" <<-EOF 2>&1 | tee -a ${OutputLogFilePath}
        $(declare -f readoptions liveLogs)
        $(declare -p ARCHIVE)
        EOF
        else 
        echo ${LIVE}
        ssh -q -T fircoadm@${line} "bash -s" <<-EOF 2>&1 | tee -a ${OutputLogFilePath}
        $(declare -f readoptions archiveLogs) #readoptions is a function to read unique ID as user input
        $(declare -p LIVE)
        EOF
        fi
    done < ${SERVERLIST}

输出:
我有 6 个远程主机,所以在终端上它打印 echo 命令(在 ssh 上声明)6 次。似乎循环在所有远程主机上执行,但我的函数代码在远程主机上不起作用。

标签: bashshell

解决方案


您必须将函数定义与子进程所需的所有其他上下文一起传递。使用以下方法,您始终是安全的:

if [[ $1 == "ARCHIVE" ]]
then
   func="archiveLogs" # --> assigning function __NAME__ to varibale
else
   func="liveLogs" # --> assigning function __NAME__ to varibale
fi

# It's easier to write a function, cause you can handle quoting easier.
some_entrypoint() {
     # Properly escape all variables
     "$func" "$ID"
}

ssh -q -T username@host "bash -s" <<EOF 2>&1 | tee -a ${OutputLogFilePath}
# Pass all functions that you will need
$(declare -f liveLogs archiveLogs some_entrypoint)
# Pass all variables that you need
$(declare -p func ID)
# Start your function
some_entrypoint
# You could use variable here, but proper "\$quoting" is painfull
# it's easier to write an entry function
EOF

不要使用function liveLogs(){. 更喜欢只是liveLogs() {


推荐阅读