首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >shell脚本中的while循环

问shell脚本中的while循环
EN

Unix & Linux用户
提问于 2018-10-03 11:59:20
回答 5查看 2.3K关注 0票数 0

我能够运行count命令,但是当我在when条件下使用它时,它会产生错误:

代码语言:javascript
复制
-bash: [/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86-64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l: No such file or directory.


count="/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86- 
64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l"
while [ "$count" -ne 0 ]
do
echo "killing services and tomcat process"
/usr/bin/ps -aef|/usr/bin/egrep "catalina|java|wrapper-linux-x86- 
64"|/usr/bin/grep -v "catalina|java"|/usr/bin/awk '{print 
$2}'|/usr/bin/xargs kill -9
sleep 10
count="/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86- 
64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l"

done;
EN

回答 5

Unix & Linux用户

发布于 2018-10-03 12:51:50

代码语言:javascript
复制
count="/usr/bin/ps -aef|...|wc -l"

不要将命令存储在变量中,它们不是为此创建的,使用存储的命令是很困难的。如果要将命令存储在某个地方,请使用函数:

代码语言:javascript
复制
count_procs() {
    /usr/bin/ps -aef|...|wc -l
}

函数可以像任何其他命令一样使用。

您所显示的代码将比较count中该字符串的值与作为整数的零值。Bash的[会抱怨一个非数字的值。

您提供的错误将来自像["$count" -eq 0 ]这样的命令(在[和$count之间没有空格),因为在这种情况下,count的内容与[连接起来,形成命令行的第一个单词,即要运行的命令的名称。虽然这样做很愚蠢,但完全有可能有一个包含括号、管道字符和空白的路径。

现在,假设您希望实际运行该命令并捕获其输出以与零进行比较,则需要使用命令替换$(...):

代码语言:javascript
复制
result=$(ps ... |wc -l)            # save the output of the command to `result`

或

代码语言:javascript
复制
[ "$(ps ... | wc -l)" -eq 0 ] ... # use the command output directly in a test

假设您希望每次循环运行时计数进程,则必须在循环体中运行该命令。因此,例如。

代码语言:javascript
复制
while [ "$(ps ... | wc -l)" -eq 0 ]; do
    ...
done

或者,用一个函数

代码语言:javascript
复制
count_procs() {
    /usr/bin/ps -aef|...|wc -l
}
while [ "$(count_procs)" -eq 0 ]; do
    ...
done  

只要在循环之前数一次进程,就会使条件成为常量,循环将无限期地重复,或者根本不重复。

票数 3
EN

Unix & Linux用户

发布于 2018-10-03 12:17:40

在while循环中,需要减少count变量。

代码语言:javascript
复制
count=10
while [ $count -ne 0 ]; do
    echo "Count is $count"
    ((count--))
done

对于实际的算术,有许多方法可以做到这一点,例如:

  • ((count--))
  • ((count-=1))
  • ((count=count-1))
  • count=$((count - 1))

有关双括号结构的更多信息,请参见:https://www.linuxtopia.org/online_书籍/高级_bash_脚本编写_指南/dblparens.html

您还可以使用let:

  • let "count--"
  • let "count-=1"
  • let "count=count-1"

有关let的更多信息,请参见:http://wiki.bash-hackers.org/commands/builtin/let

编辑:关于POSIX兼容shell的说明,它与bash不同。

Posix可以使用$(( ))语法。因此,如果上面有相同的循环,并且希望确保它能在像ksh这样的外壳上工作,或者像XPG4问题4(XPG4)这样的官方可移植的shell,那么S sh:

  • count=$((count - 1))

使用此语法将使您的脚本比使用bash特定的语法更易于移植,如果这对您很重要的话。

票数 2
EN

Unix & Linux用户

发布于 2018-10-03 16:41:59

除了有关命令替换引用的混乱之外,错误消息还指出您实际上拥有while ["$count" -ne 0],而括号周围没有所需的空间。请记住,"while“后面的部分实际上是一个命令,循环在命令以非零状态退出时结束(ref https://www.gnu.org/software/bash/manual/bashref.html#Looping-Constructs)。

由于缺少空间,bash看到

代码语言:javascript
复制
while ["/usr/bin/ps -aef|/usr/bin/egrep 'catalina|java|wrapper-linux-x86-64'|/usr/bin/grep -v 'catalina|java|wrapper-linux-x86-64'|wc -l" -ne 0]

它正在尝试执行命令 ["/usr/bin/ps -aef|...|wc -l",这显然找不到

重要的是要记住,[实际上是一个命令,因此在它之后需要一个空格来将命令名与其第一个参数分开。(与编写ls -l而不是ls-l的原因相同)。此外,[命令要求]是它的最后一个参数,因此]还需要空格分隔。

在bash提示符下,键入help [和help test (以及help [[)

票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/472962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档