Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何在出现错误时不中断循环的执行并将其写入变量?_Linux_Bash_Awk_Sed - Fatal编程技术网

Linux 如何在出现错误时不中断循环的执行并将其写入变量?

Linux 如何在出现错误时不中断循环的执行并将其写入变量?,linux,bash,awk,sed,Linux,Bash,Awk,Sed,我想通过scp备份mikrotiks。此脚本从hosts.txt循环通过主机。逐个连接到列表中的每个设备。执行备份和所有操作。如果在某个阶段无法连接到设备,则会形成一个空备份,然后发送到云。 我想查查。如果无法连接到主机,则逐行将此主机写入变量,然后转到下一个设备。接下来,我将通知所有失败的连接。 问题是,只有第一个错误被写入变量,所有后续错误都被忽略。 告诉我谁知道什么 #!/bin/bash readarray -t hosts < hosts.txt DATE=$(date +'%

我想通过scp备份mikrotiks。此脚本从hosts.txt循环通过主机。逐个连接到列表中的每个设备。执行备份和所有操作。如果在某个阶段无法连接到设备,则会形成一个空备份,然后发送到云。 我想查查。如果无法连接到主机,则逐行将此主机写入变量,然后转到下一个设备。接下来,我将通知所有失败的连接。 问题是,只有第一个错误被写入变量,所有后续错误都被忽略。 告诉我谁知道什么

#!/bin/bash
readarray -t hosts < hosts.txt

DATE=$(date +'%Y-%m-%d_%H-%M-%S')
ROS='<br>'
ERR=( )

 #Get values from main list
for host in ${hosts[*]}
do
    #Get values from sub list
    hostname=($(echo ${host} | tr "_" " "))
    echo ${hostname[0]} - ${hostname[1]}
    #connect & backup & transfer & archive & rm old files & moove to cloud
    if ssh backup@${hostname[0]} -C "/system backup save name=${hostname[1]}_$DATE"; then
        scp backup@${hostname[0]}:"${hostname[1]}_$DATE.backup" ./
        ssh backup@${hostname[0]} -C "rm ${hostname[1]}_$DATE.backup"
        tar -czvf ./${hostname[1]}_$DATE.tar.gz ${hostname[1]}_$DATE.backup
        scp ./${hostname[1]}_$DATE.tar.gz my@cloud.com:/var/www/my.cloud.com/backups/mikrotik/
        rm ${hostname[1]}_$DATE.backup ${hostname[1]}_$DATE.tar.gz
        ROS=$ROS${hostname[1]}"<br>"
    else
        ERR+=(${hosts[*]} "is not ready")
    fi
done

正如我在评论中指出的,您误用了数组表示法。您的行
ERR=(${hosts[*]}”未就绪”)
应该是
ERR+=(${hosts[*]}”未就绪”)
并且您应该将
ERR
定义为数组,而不是标量:
ERR=()
例如,或者
声明-a ERR
。类似于
ROS

下面是一个测试脚本,它避免了所有的
ssh
scp
工作,以演示通过和失败主机的列表是否工作—阵列
主机
ROS
错误
是否正确处理

请注意,
“${ERR[@]}”
使用双引号和
@
代替无引号和
*
。差异很重要,因为数组中的值包含空格。尝试其他选择。还要注意的是,
printf
始终打印,即使格式字符串中没有与
%s
对应的参数。因此,在调用
printf
之前,需要检查数组中的元素数

#/bin/bash
#需要Bash4.x-Mac上的Bash3.2不支持readarray
#readarray-t hosts
输出:

==PASS===[passed-1 passed]
==通过==[通过-3通过]
==通过==[通过-5次通过]
!! 失败!![失败-2失败]
!! 失败!![失败-4失败]
==通过==[通过-1通过]
==通过==[通过-3通过]
==通过==[通过-5次通过]
!! 失败!![失败-2失败]
!! 失败!![失败-4失败]

很抱歉,备份您的数据失败太多

记录的是第一台或最后一台不可用的主机?您的行
ERR=(${hosts[*]}”未就绪”)
应该是
ERR+=(${hosts[*]}”未就绪”)
并且您应该将
ERR
定义为数组,而不是标量:
ERR=()
例如,或者
声明-a ERR
。类似于
ROS
。将脚本复制/粘贴到中,并修复它告诉您的问题,如果您仍然有问题,则将结果发布到问题中。@JonathanLeffler感谢您的替换,现在我将修复它并重试。@JonathanLeffler第一个不可用的主机已写入文件。由于您显示的代码中没有任何状态信息写入文件,因此我断定您讨论的是尚未显示的代码。您可能应该将
ROS=$ROS${hostname[1]}“
写成
ROS=“$ROS${hostname[1]}
,将整个RHS括在双引号中。我相信您知道这一点,但为了操作起见-不要对未导出的变量名(
ROS
ERR
)使用所有大写字母,看到了,我故意忽略了这一点,因为这与我学习编写shell脚本的方式相反,但您可能最适合这些天学习shell脚本的人。事实上,我对环境变量大多使用大写下划线的名称,而对其他变量使用小写下划线的名称。还有一个关于太的问题(链接自Unix和Linux问题)。在没有外部胁迫的情况下,我很少(如果有的话)使用小写的环境变量名。这听起来与我给出的建议并不矛盾,对我来说也是一样的——对环境变量使用大写,否则使用小写。也许我用了双底片,这就不清楚了!
hosts.txt
10.10.8.11_CAP-1
10.10.9.12_CAP-2
10.10.10.13_CAP-3