我编写了一个简单的 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
循环在空格或制表符上分割文件(从技术上讲,文件的文件名中也有换行符:您不太可能遇到这样的情况)文件,在这种情况下,如果您确实遇到这样的文件,它不会导致严重的问题,但值得注意这种可能性,以防万一它确实重要)。 - 为了使带有空格的文件名不变成
-f
and的几个不同参数-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