如何修复bash脚本中的“太多参数”错误

时间:2019-08-27 19:08:45

标签: bash shell

我对这部分代码有疑问; 我该如何解决? 当我在第6行(第一个if语句)上运行此脚本错误时

#!/bin/bash
state=false
for i in 'systemctl list-units | grep .service | grep running | awk '{print $1}' | cut -d '.' -f 1'
do
    if [ $i = "cron" ]  
    then
        state=true
        break
    fi
done

if [ $state = "flase" ]
then
    echo " CRON Service is Stopped !" 
fi

我试图用{;”结尾更改if [ $i = "cron" ] 但没有用!

if [ $i = "cron" ]  
    then
    state=true
    break
fi

输出错误...

1 个答案:

答案 0 :(得分:3)

该错误是在for循环中进行的设置。

第一行

for i in 'systemctl list-units | grep .service | grep running | awk '{print $1}' | cut -d '.' -f 1'

那些单引号(')应该是反引号(`),以获得任何实际结果。最好使用$(...),因为它更容易阅读。此格式也与反向标记具有相同的含义。因此,这将为您提供所需的结果:

for i in $(systemctl list-units | grep .service | grep running | awk '{print $1}' | cut -d '.' -f 1)

发生错误的原因是,您正在$(...)之间将命令作为单个字符串发送到for循环中。因此,您正在遍历该字符串,而不是其输出。当您到达if语句时,它的含义是:

if [ systemctl list-units | grep .service | grep running | awk {print $1} | cut -d . -f 1 = "cron" ]

[...]之间的每个空格都构成一个新参数。因此出现错误“参数过多”。正如@oguzismail所建议的那样,引号$i是理想的选择,它可以避免出现错误消息,但是您将无法获得理想的结果。

另外,为了将来参考,while read循环通常更适合此工作。在此特定示例中,您会没事的,因为服务中不应有任何空格。如果存在空格,您将需要执行一些$IFS恶作剧以使for循环以您希望的方式运行,而while read循环只能安全地在行上拆分。更多信息here

编辑:这里有一些我以前没有注意到的问题。我实际上只是注意到您在这里使用了truefalse(我会假设拼写错误是复印错字):

if [ $state = "flase" ]

truefalse实际上是(可能)引用/usr/bin/true/usr/bin/false的程序,它们分别返回0和1。作为优先事项,我将这一行写为:

if ! $state

您将遇到的另一个问题是:

echo " CRON Service is Stopped !"

!是用于历史记录的特殊字符,它将尝试在双引号内进行扩展。为了避免这种情况,只需在此处使用单引号即可:

echo ' CRON Service is Stopped !'

现在,已找到您的错误,这是编写此脚本的另一种方法。为了便于阅读,我将其分成多行,但您可以将所有内容放在一行上:

#!/bin/bash

# This is the same as the original command with an additional grep -q (quiet).
# If the last grep finds the cron service, the return code ($?) is 0.
# The command after || only executes if the last command fails ($? not 0).
systemctl list-units |
  grep .service |
  grep running |
  awk '{print $1}' |
  cut -d '.' -f 1 |
  grep -q '^cron$' ||
  echo ' CRON Service is Stopped !'