Linux 捕获bash脚本中的命令的输出,该脚本将记录错误

Linux 捕获bash脚本中的命令的输出,该脚本将记录错误,linux,bash,Linux,Bash,OS:lubuntu 13.04 我正在运行一个简单的bash脚本,将各种系统信息保存到一个文件中。我主要是将命令的输出回显到一个文件中。我运行的命令之一是: echo "$(nmcli dev list)" >> $CI 我注意到在某些系统上,上面的命令将返回空白 如果直接从CLI运行“nmcli dev list”,我注意到nmcli会得到一个segfault,因此echo不会将该命令的任何内容放入$CI文件中 虽然这里真正的问题是nmcli有一个segfault,但在“nmc

OS:lubuntu 13.04

我正在运行一个简单的bash脚本,将各种系统信息保存到一个文件中。我主要是将命令的输出回显到一个文件中。我运行的命令之一是:

echo "$(nmcli dev list)" >> $CI
我注意到在某些系统上,上面的命令将返回空白

如果直接从CLI运行“nmcli dev list”,我注意到nmcli会得到一个segfault,因此echo不会将该命令的任何内容放入$CI文件中

虽然这里真正的问题是nmcli有一个segfault,但在“nmcli dev list”的输出中仍然有一些有价值的信息,我希望保存这些信息,直到它出现segfault

考虑到我在这个网站和谷歌搜索上所发现和阅读的内容,似乎没有太容易的答案,因为由于SEGFULT命令从未完成。但是,我希望有人能想出一个解决办法或其他技术来捕获输出,直到出现故障

user1@comp1:/home/user1$ nmcli dev list
GENERAL.DEVICE:                         eth0
GENERAL.TYPE:                           802-3-ethernet
GENERAL.VENDOR:                         Marvell Technology Group Ltd.
GENERAL.PRODUCT:                        88E8040 PCI-E Fast Ethernet Controller
GENERAL.DRIVER:                         sky2
GENERAL.DRIVER-VERSION:                 1.30
GENERAL.FIRMWARE-VERSION:
GENERAL.HWADDR:                         00:24:81:5D:F3:F9
GENERAL.STATE:                          20 (unavailable)
GENERAL.REASON:                         2 (Device is now managed)
GENERAL.UDI:                            /sys/devices/pci0000:00/0000:00:1c.1/0000:02:00.0/net/eth0
GENERAL.IP-IFACE:
GENERAL.NM-MANAGED:                     yes
GENERAL.AUTOCONNECT:                    yes
GENERAL.FIRMWARE-MISSING:               no
GENERAL.CONNECTION:                     not connected
CAPABILITIES.CARRIER-DETECT:            yes
CAPABILITIES.SPEED:                     unknown
Segmentation fault
使用bash-x运行我的脚本的结果:

+ echo '    <NMCLI> '
++ nmcli dev list
+ echo ''
+ echo '    </NMCLI> '
+echo''
++nmcli开发列表
+回声“
+回声“
整个脚本:

#!/bin/bash

# Define file to save configuration info to
CI=config-info.txt

# Get hostname
HOSTNAME=$(hostname)
echo "    <Hostname>$HOSTNAME</Hostname>" >> $CI

# Get IP
IP=$(ifconfig | grep -m 1 -E '(inet.*Bcast.*Mask)' | awk '{print $2}' | sed s/addr:/""/)
echo "    <IP>$IP</IP>" >> $CI

# Get SubnetMask
MASK=$(ifconfig | grep -m 1 -E '(inet.*Bcast.*Mask)' | awk '{print $4}' | sed s/Mask:/""/)
echo "    <SubnetMask>$MASK</SubnetMask>" >> $CI

# Get Gateway IP
GATEWAY=$(ip route show | grep  -m 1 'default via' | awk '{print $3}')
echo "    <Gateway>$GATEWAY</Gateway>" >> $CI

# Get DNS Server IP
DNS=$(nmcli dev list | grep -m 1 DNS | awk {'print $2'})
echo "    <DNS>$DNS</DNS>" >> $CI

# Get MAC Address of NIC
MAC=$(ifconfig | grep -m 1 HWaddr | awk '{print $5}')
echo "    <MAC>$MAC</MAC>" >> $CI

# Get System Uptime
UPTIME=$(cat /proc/uptime | awk '{print $1}')
echo "    <Uptime>$UPTIME</Uptime>" >> $CI

# Get NIC linkspeed
LINKSPEED=$(nmcli dev list | grep -m 1 CAPABILITIES.SPEED | awk '{print $2 " " $3}')
echo "    <LinkSpeed>$LINKSPEED</LinkSpeed>" >> $CI

# Get NIC Vendor
# The first awk gets all columns in the line excluding the 1st column.
# The second awk removes the leading space in front of the output of the first awk
NICVENDOR=$(nmcli dev list | grep -m 1 GENERAL.VENDOR | awk '{$1=""; print $0}' |  awk '{sub(/^[ \t]+/, "")};1'
)
echo "    <NicVendor>$NICVENDOR</NicVendor>" >> $CI

# Get NIC Model
NICMODEL=$(nmcli dev list | grep -m 1 GENERAL.PRODUCT | awk '{$1=""; print $0}' |  awk '{sub(/^[ \t]+/, "")};1')
echo "    <NicModel>$NICMODEL</NicModel>" >> $CI

# Get NIC Driver Name
NICDRIVER=$(nmcli dev list | grep -m 1 GENERAL.DRIVER | awk '{$1=""; print $0}' |  awk '{sub(/^[ \t]+/, "")};1')
echo "    <NicDriver>$NICDRIVER</NicDriver>" >> $CI

# Get NIC Driver Version
NICDRIVERVERSION=$(nmcli dev list | grep -m 1 GENERAL.DRIVER-VERSION | awk '{$1=""; print $0}' |  awk '{sub(/^[ \t]+/, "")};1')
echo "    <NicDriverVersion>$NICDRIVERVERSION</NicDriverVersion>" >> $CI

# Get "ifconfig -a" information
echo "    <Ifconfig>" >> $CI
echo "$(ifconfig -a)" >> $CI
echo "    </Ifconfig>" >> $CI

# Get "nmcli dev list" information
echo "    <NMCLI> "  >> $CI
echo "$(nmcli dev list)" >> $CI
echo "    </NMCLI> "  >> $CI

# Get "nmcli -p dev wifi list" output - This lists all detected Wireless Networks
echo "    <Wireless>" >> $CI
echo "$(nmcli -p dev wifi list)" >> $CI
echo "    </Wireless>" >> $CI

# Get "nmcli -p con status" output - Shows the status for all known network connections
echo "    <ConnectionsStatus>" >> $CI
echo "$(nmcli -p con status)" >> $CI
echo "    </ConnectionsStatus>" >> $CI

# Get "nmcli -p con list" output - Lists all connections NetworkManager has
echo "    <ConnectionsAll>" >> $CI
echo "$(nmcli -p con list)" >> $CI
echo "    </ConnectionsAll>" >> $CI

# Get "route" information
echo "    <Route>" >> $CI
echo "\"route\": " >> $CI
echo "$(route)" >> $CI
echo " " >> $CI
echo "\"route -n\": " >> $CI
echo "$(route -n)" >> $CI
echo " " >> $CI
echo "\"route -Cn\": " >> $CI
echo "$(route -Cn)" >> $CI
echo "    </Route>" >> $CI
#/bin/bash
#定义要将配置信息保存到的文件
CI=config-info.txt
#获取主机名
主机名=$(主机名)
回显“$HOSTNAME”>>$CI
#获取IP
IP=$(ifconfig | grep-m1-E'(inet.*Bcast.*Mask)| awk'{print$2}'| sed s/addr:/“”/)
回显“$IP”>>$CI
#获取子网掩码
MASK=$(ifconfig | grep-m1-E'(inet.*Bcast.*MASK)| awk'{print$4}'| sed s/MASK:/“”/)
回显“$MASK”>>$CI
#获取网关IP
网关=$(ip路由显示| grep-m1'通过| awk'{print$3}'默认)
回显“$GATEWAY”>>$CI
#获取DNS服务器IP
DNS=$(nmcli开发列表| grep-m1dns | awk{'print$2'})
回显“$DNS”>>$CI
#获取NIC的MAC地址
MAC=$(ifconfig | grep-m 1 HWaddr | awk'{print$5}')
回显“$MAC”>>$CI
#获取系统正常运行时间
正常运行时间=$(cat/proc/UPTIME | awk'{print$1}')
回显“$UPTIME”>>$CI
#获取NIC链接速度
LINKSPEED=$(nmcli开发列表| grep-m1 CAPABILITIES.SPEED | awk'{print$2”“$3}')
回显“$LINKSPEED”>>$CI
#获取NIC供应商
#第一个awk获取行中除第一列以外的所有列。
#第二个awk删除第一个awk输出前面的前导空间
NICVENDOR=$(nmcli dev list | grep-m 1 GENERAL.VENDOR | awk'{$1=”“;print$0}'| awk'{sub(/^[\t]+/,“”)};1'
)
echo“$NICVENDOR”>>$CI
#获取NIC模型
NICMODEL=$(nmcli开发列表| grep-m1 GENERAL.PRODUCT | awk'{$1=”“;print$0}'| awk'{sub(/^[\t]+/,“”)};1')
回显“$NICMODEL”>>$CI
#获取NIC驱动程序名称
NICDRIVER=$(nmcli dev list | grep-m1 GENERAL.DRIVER | awk'{$1=“;print$0}'| awk'{sub(/^[\t]+/,“”)};1')
回显“$NICDRIVER”>>$CI
#获取NIC驱动程序版本
NICDRIVERVERSION=$(nmcli开发列表| grep-m1 GENERAL.DRIVER-VERSION | awk'{$1=”“;print$0}'| awk'{sub(/^[\t]+/,“”)};1')
回显“$NICDRIVERVERSION”>>$CI
#获取“ifconfig-a”信息
echo”“>>$CI
echo“$(ifconfig-a)”>>$CI
echo”“>>$CI
#获取“nmcli开发列表”信息
echo”“>>$CI
回显“$(nmcli开发列表)”>>$CI
echo”“>>$CI
#获取“nmcli-p dev wifi list”输出-列出所有检测到的无线网络
echo”“>>$CI
echo“$(nmcli-p开发wifi列表)”>>$CI
echo”“>>$CI
#获取“nmcli-p con status”输出-显示所有已知网络连接的状态
echo”“>>$CI
回显“$(nmcli-p con状态)”>>$CI
echo”“>>$CI
#获取“nmcli-p con list”输出-列出NetworkManager拥有的所有连接
echo”“>>$CI
回显“$(nmcli-p con list)”>>$CI
echo”“>>$CI
#获取“路线”信息
echo”“>>$CI
回显“\”路由\”:“>>$CI
回显“$(路由)”>>$CI
echo”“>>$CI
回显“\”路由-n\”:“>>$CI
echo“$(路由-n)”>>$CI
echo”“>>$CI
回显“\”路由-Cn\”:“>>$CI
回显“$(路由-Cn)”>>$CI
echo”“>>$CI

您是否尝试将stdout和stderr重定向到您的文件

根据在找到的文档,您可以使用&>重定向到文件,也可以使用2>&1将stderr重定向到stdout

nmcli dev list &>> $CI
这就是你所需要的。如果您运行的是较旧版本的bash,请尝试以下操作

nmcli dev list >> $CI 2>&1 
注意:如果出于某种原因仍然需要
echo
,则需要将重定向放在子shell中,并放在命令或分组之后,然后重定向整个输出,如

echo "$(nmcli dev list >> $CI 2>&1)" >> $CI 2>&1 


你在地下室里运行它。为什么不直接运行它呢<代码>nmcli开发列表>>foo.txt?感谢您的快速回复。我最初试着像你提到的那样直接做,但它的行为方式是一样的。foo.txt仍然是空的。我想我在各种尝试中都把它添加到了一个子shell中,但我已经失去了方向,因为为了让它工作,所有的头都撞到了桌子上:)@Marc B只是为了确定一下,我刚才直接重新运行了,foo.txt是空的,CLI在CLI.odd上显示了“分段错误”。也许那个文本实际上是stderr的输出?你试过重定向吗<代码>2>&1>>foo.txt?@Marc B:这很奇怪,因为重定向stderr的结果是一样的<代码>user1@comp1:/home/user1$nmcli dev list 2>&1>>foo.txt分段错误user1@comp1:/home/user1$nmcli dev list&>>foo.txt分段错误user1@comp1:/home/user1$cat foo.txtuser1@comp1:/home/user1$这很奇怪,因为重定向stderr的结果是相同的<代码>user1@comp1:/home/user1$nmcli dev list 2>&1>>foo.txt分段错误user1@comp1:/home/user1$nmcli dev list&>>foo.txt分段错误user1@comp1:/home/user1$cat foo.txtuser1@comp1:/home/user1$您可以尝试捕获故障。检查中的第一个答案和用户在注释中提供的示例。@spetz如果
旧版本的
向后,它应该是
nmcli dev list>$CI 2>&1
@MontyP Try
nmcli dev list>>foo.txt 2>&1
。重定向到当前fd所指向的位置,但在更改时不会跟随。@spetz现在应该可以为他工作+1。还编辑了关于重定向i的部分
{ echo "$(nmcli dev list)"; } >> $CI 2>&1