显示目录列表的 Bash 脚本出现错误

显示目录列表的 Bash 脚本出现错误

我编写了一个简单的 bash 脚本(我对它还很陌生,你知道!)来接受目录作为其参数并打印其列表,测试文件和目录。我是这样处理的:

#!/bin/bash
# Lists all files and directories (non-recursively) in a specified directory

if [ $# -gt 1 ]; then
    echo "Error. Please specify only one directory. ($#)"
    exit
fi

if [ -z $1 ]; then
    echo "No directory specified. Exiting."
    exit
fi

echo "Listing for $1:"

$dirs=`ls $1`
echo "Dirs: $dirs" # Just to confirm if all is well

# Loop through and print
for i in $dirs;
do
    if [ -f $i ]; then
        echo "File: $i"
    elif [ -d $i ]; then
        echo "Directory: $i"
    fi
done

问题出在我的 for 循环中。当我运行此脚本并将其提供给我的主目录时,我收到此错误:

./list_files_and_dirs.sh: line 16: =Calibre: command not found

我知道我在涉及变量的命令替换中犯了错误,但我只是不知道是什么。请有人帮忙!

=================更新=================

这是根据答案输入的新(最后部分)代码:

dirs=`ls "$1"`
#echo "Dirs: $dirs" # Just to confirm if all is well

IFS=$'\n'

# Loop through and print
for i in $dirs;
do
    if [ -f "$i" ]; then
        echo "File: $i"
    elif [ -d "$i" ]; then
        echo "Directory: $i"
    fi
done

答案1

注意:我假设您正在自学 Bash。不要在生产中使用此代码。find "$directory" -maxdepth 1 -type d将为您提供目录,-type f将为您提供文件。

既然它抱怨第 16 行,让我们看一下:

$dirs=`ls $1`

如果要分配给变量,则不应包含$.我猜你的意思是:

dirs=`ls $1`

现在发生的事情是这样的:

  • $dirs可能是空的,所以什么都没有替代。
  • ls命令将运行,其输出将替换为“命令”。
  • 目录中的第一个文件称为Calibre,留下命令:=Calibre x y z ...
  • =Calibre不是有效的命令,因此会出现错误。

然而,我们还没有做到这一点:如果任何文件名中有空格,这就会出错。要解决这个问题,您需要做更多的事情:

  • 您需要在循环IFS=$'\n'之前包含某处for。这将字段分隔符设置为换行符,从而阻止for循环在空格或制表符上分割文件(从技术上讲,文件的文件名中也有换行符:您不太可能遇到这样的情况)文件,在这种情况下,如果您确实遇到这样的文件,它不会导致严重的问题,但值得注意这种可能性,以防万一它确实重要)。
  • 为了使带有空格的文件名不变成-fand的几个不同参数-d,您需要加上引号$i。 (所以:[ -f "$i" ][ -d "$i" ]。为了支持其中包含空格的目录,您应该对$1使用它的地方执行相同的操作。

答案2

马里努斯已经解释了为什么你会收到这个错误。我想指出的是,这里没有必要ls。这样,您就可以避免随之而来的所有问题解析其输出。你可以这样做:

#!/bin/bash
# Lists all files and directories (non-recursively) in a specified directory

if [ "$#" -gt 1 ]; then
    echo "Error. Please specify only one directory. ($#)"
    exit
fi

if [ -z "$1" ]; then
    echo "No directory specified. Exiting."
    exit
fi

echo "Listing for $1:"

# Loop through and print
for i in "$1"/*;
do
    if [ -f "$i" ]; then
        echo "File: $i"
    elif [ -d "$i" ]; then
        echo "Directory: $i"
    fi
done

相关内容