Ete*_*our 4 bash shell-script command-substitution
我写了一些 shell 脚本,但从未见过这种行为,我不知所措。我有以下在 bash shell 中运行的简单脚本:
LOGFILE="/var/log/constructor-events.txt"
SUBSYSTEM="$1"
DEVTYPE="$2"
DEVICE="$3"
VENDOR=$(lsusb -D "$DEVICE" | grep idVendor 2>&1)
REQUEST=$(cat <<EOF
{"data": {
"action": "add",
"port": {
"type": "$SUBSYSTEM",
},
"drive": {
"vendor_id": "$VENDOR",
}
}}
EOF
)
printf "output: $VENDOR" >> $LOGFILE
printf "%s\n" "`date +%x\ %r\ %Z` $REQUEST" >> $LOGFILE
Run Code Online (Sandbox Code Playgroud)
这是从 udev 规则执行的。位置参数(来自 udev)具有我期望的值,我将它们打印到日志文件没有问题。但出于某种原因,该$VENDOR变量不包含lsusb命令的输出。
这是我完成的调试。
$VENDOR变量直接发送到日志的行,该行为空。$VENDOR变量打印到终端,它是空的。取出包含在$DEVICE变量中的字符串并直接在shell中执行,得到这个结果。
[root@host ~]# lsusb -D /dev/bus/usb/016/030 | grep idVendor
Cannot open /dev/bus/usb/016/030
Run Code Online (Sandbox Code Playgroud)为什么$VENDOR输出到日志文件时变量为空?
编辑:
这是从命令替换中删除重定向后的更新。
$VENDOR变量打印到终端。$DEVICE变量。打印$VENDOR到终端输出错误,但它仍然没有附加到日志文件中!$DEVICE日志文件中IS的值。我相信它与命令替换中的输出重定向有关。
在这里,如果lsusb丢弃错误,则不会重定向错误消息,只会重定向来自grep. 错误lsusb仍然是通常的stderr,即终端(或stderr脚本启动时的任何错误。
VENDOR=$(lsusb -D "$DEVICE" | grep idVendor 2>&1)
Run Code Online (Sandbox Code Playgroud)
例如
$ blah=$(ls -l /nonexisting | grep foo 2>&1)
ls: cannot access '/nonexisting': No such file or directory
$ echo "blah: '$blah'"
blah: ''
Run Code Online (Sandbox Code Playgroud)
您需要将它们的两个输出作为一个组重定向,以便命令替换也捕获错误:
$ blah=$( { ls -l /nonexisting | grep foo; } 2>&1)
$ echo "blah: '$blah'"
blah: 'ls: cannot access '/nonexisting': No such file or directory'
Run Code Online (Sandbox Code Playgroud)
使用单独的重定向,例如$( foo 2>&1 | grep 2>&1 )将第一个命令的错误发送到管道,并进行grep过滤,在上面的示例中将再次产生空输出。
| 归档时间: |
|
| 查看次数: |
2874 次 |
| 最近记录: |