解释Bash if / else语句中的shell命令

时间:2010-07-08 14:04:34

标签: bash

在尝试创建条件语句来检查目录中的文件数量时,我偶然发现了一个问题。我编写此脚本的最初方式是:

ELEM=`ls -l $DIR | wc -l` 
if [ $ELEM -lt 5 ] ; then

的工作原理。但是我想将$ ELEM移动到条件参数块中,以便在我到达if语句时对其进行解释。我尝试过使用单引号,双引号,后退标记和括号的不同组合。

有谁知道如何解决这个问题?

5 个答案:

答案 0 :(得分:2)

切勿在批处理模式下使用ls,而是使用globbing。还要避免反引号,不带引号的变量和内置[

shopt -s nullglob  # expand to an empty array if directory is empty
shopt -s dotglob   # also glob dotfiles
files=("$DIR"/*)
count=${#files[@]}
if ((count > 5))
then
  ...
fi

答案 1 :(得分:0)

出于某种原因,直到现在才使用它:

ELEM="`ls -l $DIR | wc -l`"

感谢您的时间。

答案 2 :(得分:0)

您似乎希望能够做的事情是C允许的:

if (elem = countfiles(dir) < 5)

Bash可以这样做:

if (( (elem = $(ls "$DIR" 2>/dev/null | wc -l) ) < 5))

或者你可以创建一个名为countfiles的函数并像这样使用它:

if (( ( elem = $(countfile "$DIR") ) < 5))

其中函数可能类似于:

countfiles() {
    find "$1" -maxdepth 1 -type f | wc -l
}

答案 3 :(得分:0)

到目前为止发布的大多数解决方案都是(恕我直言)过于复杂。只要系统上的ls命令支持-B选项(将特殊字符显示为八进制转义序列),您就可以使用:

if [[ $(ls -B "$DIR" | wc -l) -lt 5 ]]; then

请注意,虽然解析ls通常是一个坏主意,但在这种情况下,我们所要做的就是找到列表的数量,因此错误比通常少得多。事实上,wc -l唯一关心的是行数,所以唯一可能出错的是文件名中可能有一个换行符,因此被误认为是两个文件名;使用-B选项ls可以防止这种情况发生,因此最终会安全起见(至少就我所见)。

答案 4 :(得分:0)

改进的countfiles函数(不会被文件名中的换行混淆):

countfiles() {
   find "$1" -maxdepth 1 -type f -print0 | tr -dc '\0' | wc -c
}