目录

sh -c的必要性

bash脚本排错技巧

"[: =: unary operator expected"的解决办法


sh -c的必要性

在Linux使用 echo 并配合命令重定向是实现向文件中写入信息的快捷方式。

比如要向 test.asc 文件中随便写入点内容,可以:
$ echo "信息" > test.asc
# 或者
$ echo "信息" >> test.asc
下面,如果将 test.asc 权限设置为只有 root 用户才有权限进行写操作:
$ sudo chown root.root test.asc
然后,我们使用 sudo 并配合 echo 命令再次向修改权限之后的 test.asc 文件中写入信息:
$ sudo echo "又一行信息" >> test.asc
-bash: test.asc: Permission denied
这时,可以看到 bash 拒绝这么做,说是权限不够。我们使用 sudo 只是让 echo 命令具有了 root 权限,但是没有让 “>” 和 ">>" 也具有 root 权限,所以 bash 会认为这两个重定向符号都没有像 test.asc 文件写入信息的权限。
解决这一问题的途径有两种。第一种是利用 "sh -c" 命令,它可以让 bash 将一个字串作为完整的命令来执行,这样就可以将 sudo 的影响范围扩展到整条命令。具体用法如下:
$ sudo sh -c 'echo "又一行信息" >> test.asc'

另一种方法是利用管道和 tee 命令,该命令可以从标准输入中读入信息并将其写入标准输出或文件中,具体用法如下:
$ echo "第三条信息" | sudo tee -a test.asc
注意,tee 命令的 "-a" 选项的作用等同于 ">>" ,如果去除该选项,那么 tee 命令的作用就等同于 ">" 。

bash脚本排错技巧

下面会给出一些实用的排错小技巧,对于快速定位问题脚本会有非常大的帮助。
下面是主要的 Shell 脚本调试选项:

-v (verbose 的简称) - 告诉 Shell 读取脚本时显示所有行,激活详细模式。
-n (noexec 或 no ecxecution 简称) - 指示 Shell 读取所有命令然而不执行它们,这个选项激活语法检查模式。
-x (xtrace 或 execution trace 简称) - 告诉 Shell 在终端显示所有执行的命令和它们的参数。 这个选项是启用 Shell 跟踪模式。
[root@zabbix-proxy ~]# cat 1.txt
ls
date
[root@zabbix-proxy ~]# /bin/bash -x 1.txt
+ ls
1.awk       2.pcap  6.sql  gitdemo                           mysql_script                   test
1.cap       2.sql   A      linux_amd64                           percona-toolkit-2.2.7-1.noarch.rpm      test.sh
+ date
Mon May 22 06:11:34 EDT 2023

"[: =: unary operator expected"的解决办法

shell脚本报错"[: =: unary operator expected"或者[: !=: unary operator expected"的解决方案

在匹配字符串相等时,我用了类似这样的语句:

[root@192 ~]# if [ $state = "OK" ]; then echo "OK"; fi
-bash: [: =: unary operator expected

在运行时出现了“ [: =: unary operator expected” 的错误,就一直找不到原因,尝试了删除等号两侧的空格和括号里的空格都不管用。最后baidu了一下,才找到原因,在条件表达式外再添加一层“[]”,就不会出错了,如下:

[root@192 ~]# if [[ $state = "OK" ]]; then echo "OK"; fi

究其原因,是因为如果变量STATUS值为空,那么条件表达式[ $state = "OK" ]就成了 [ = "OK"] ,显然 [ 和 "OK" 不相等并且缺少了 [ 符号,所以报了这样的错误。当然不总是出错,如果变量STATUS值不为空,程序就正常了,所以这样的错误还是很隐蔽的。

或者,用下面的方法也能避免这种错误:

[root@192 ~]# if [ "$state" = "OK" ]; then echo "OK"; fi       ##"$state"表示变量$state为空的时候"$state"为空字符串,并非什么都没有。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐