bash - 寻找一种在 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 次。似乎循环在所有远程主机上执行,但我的函数代码在远程主机上不起作用。
解决方案
您必须将函数定义与子进程所需的所有其他上下文一起传递。使用以下方法,您始终是安全的:
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() {
。
推荐阅读
- java - Java:如何根据对象列表向数据框添加列
- javascript - Discord.js 通过 ID 或名称提及用户
- sql-server - SQL Server:使用子查询选择数据时,子查询返回超过 1 个值
- gradle - GitLab 插件 SonarQube MR 分析
- ruby - 有人喜欢挑战吗?minimax 井字游戏
- json - Symfony4 使用 crud 生成 API 休息
- typescript - 仅在不可分配类型的情况下,如何用未定义(在对象属性中)替换空值?
- javascript - Angular:我必须存储对象形式的 api 响应以进一步使用。请让我知道存储该响应的便捷方式
- javascript - 比较数组并将更改保存在更改数组中
- python - jupyter笔记本中全局变量更改的自动化