linux 从bash脚本将变量传递到交互式会话之外

flseospp  于 2023-02-15  发布在  Linux
关注(0)|答案(1)|浏览(127)

全世界的人们好,
我试图写一个脚本,将允许用户在bash站点之间故障转移应用程序。
我们的应用程序是由Pacemaker控制的,我想我将能够编写一个函数,它将接受必要的变量并执行。在一个站点停止,在另一个站点开始。一旦我将ssh“d连接到远程计算机,我就无法获取grep/awk命令的值以获取PCS中应用程序的状态。
我遇到了一些问题,并已尝试从stackoverflow和其他网站的答案。
1.我将ssh命令发送到/dev/null 2>&1,因为unix管理员在本地用户的屏幕上弹出横幅,-q不处理它-这是否会阻止返回任何内容?
1.当在代码中使用awk '{print \\\\\\$4}'时,我得到一个“反斜杠不是行的最后一个字符”错误
1.为了解决这个问题,我尝试了result=$(sudo pcs status | grep nds_$resource),但是这导致了sudo上的密码错误
1.我试过>/dev/tty and >$(tty)
1.我尝试不抑制ssh(删除/dev/null 2>&1),并在函数调用时将输出放在变量中,从sudo pcs status条目中删除awk

result=$(pcs_call "$site1" "1" "2" "disable" "pmr")
echo $result | grep systemd

这是可以的,但是当我添加| awk '{print \\\$4}'时,我得到了横幅中的第四个单词。
任何帮助将不胜感激,因为我已经在这几天了。
我一直在看Bruno的回答,但不确定如何实现,因为我有多个sudo命令。
下面是我在一台机器上测试的功能代码;

site1=lon
site2=ire

function pcs_call()
{
 site=$1
 serverA=$2
 serverB=$3
 activity=$4
 resource=$5

ssh -tt ${site}servername0${serverA}  <<SSH > /dev/null 2>&1
         sudo pcs resource ${activity} proc_${resource}
         sleep 10
         sudo pcs status  | grep proc_$resource | awk '{print \\\$4}' | tee $output
         exit
SSH
echo $output
}

echo ====================================================================================
echo Shutting Down PMR in $site1
pcs_call "$site1" "1" "2" "disable" "pmr"
ubof19bj

ubof19bj1#

我会说,从粘贴整个东西到www.example.com和修复错误,直到没有建议开始,但这里有一些 * 严重 * 的问题,shellcheck是无法单独处理的。ShellCheck.net and fixing errors until there are no suggestions, but there are some serious issues here shellcheck is not going to be able to handle alone.

  1. > /dev/null表示"将返回的任何数据丢弃到位桶中。2>&1表示"无论stdout去往何处,都发送有关stderr的任何有用的错误报告"。您的初始语句旨在从远程系统检索信息,但会立即丢弃它。除非您只是希望在远程系统上发生您不"希望"在本地了解更多信息的事情,在那之后,你是在浪费你的时间,因为你已经抛弃了它所说的一切。
    1.在awk语句中只需要一个反斜杠就可以在$4上引用美元符号。
    1.除非您在远程系统上有无密码的sudo,否则这对您来说是行不通的。我认为在深入讨论之前,我们需要更多的信息。
    1.只要ssh调用将所有内容都抛给/dev/null,则正在传递的代码块中***没有任何内容***会在调用系统上给您任何结果。
    1.在你的代码中,你使用的是$output,但是看起来好像你想让tee成为 * setting * it?That's not how that workstee的参数是一个 * filename ,它希望将数据的副本写入其中,它 * 也 * 将数据流到stdout( tee *,就像管道中的"T"型接头一样),但是它不分配变量。
    (As另外,您甚至还没有使用serverB,但是当您解决了当前的问题后,您可以重新添加它。)
    最后你得到echo $output,它可能是空的,所以它基本上只是echo,除了一个换行符外什么都不发送,换行符只会被发送回源服务器并转储到/dev/null中,所以这一切都是毫无意义的......
    让我们清理一下
sudo pcs status | grep proc_$resource | awk '{print \\\$4}' | tee $output

试着改变一下,好吗
首先,我将假设您有无密码的sudo,否则将有一个完整的其他对话来解决这个问题。
其次,在管道中同时使用grep * 和 * awk * 通常是一个反模式,因为它们本质上都是正则表达式引擎。选择一个。如果您可以让grep做您想做的事情,那么它非常高效。如果不能,awk * 超级 * 灵活。***当某些工具无法正常工作时,请***阅读有关您正在使用的工具的文档页面。快速搜索"bash man grep"或"awk manual"会很快给你提供大量的资源,如果你想做这么复杂的事情,你会需要它们。
所以,让我们重新考虑一下,做一些假设...

function pcs_call() {
  local site="$1" serverA="$2" activity="$3" resource="$4" # make local and quotes habits you only break on purpose
  ssh -qt ${site}servername0${serverA} "
    sudo pcs resource ${activity} proc_${resource}; sleep 10; sudo pcs status; 
  " 2>&1 | awk -v resource="$resource" '$0~"proc_"resource { print $4 }'
}

pcs_call "$site1" 1 disable pmr # should print the desired field

如果你想把数据保存在变量中以便以后使用-

var1="$( pcs_call "$site1" 1 disable pmr )"

附录

解决您的问题-使用$(seq 1 10)或仅使用{1..10}

ssh -qt chis03 '
    for i in {1..10}; do sudo pcs resource disable ipa $i; done;
    sleep 10; sudo pcs status;
' 2>&1 | awk -v resource=ipa '$0~"proc_"resource { print $2" "$4 }'

它首先报告awk,因为流水线中元素的顺序是"未定义的",但是ssh的stdout被插入到awk的stdin中(由于它被复制到stdout,所以stderr也是),所以它们异步/同时运行。
是的,因为这些都是使用文字,单引号是更简单和有效的"更好"。如果抽象与变量,它没有太大的变化,但切换回双引号。

# assuming my vars (svr, verb, target) preset in the context
ssh -qt $svr "
    for i in {1..10}; do sudo pcs resource $verb $target \$i; done;
    sleep 10; sudo pcs status;
" 2>&1 | awk -v resource="$target" '$0~"proc_"resource { print $2" "$4 }'

有帮助吗?

相关问题