我对 unix 和脚本编写还很陌生,我正在尝试编写一个脚本,该脚本可以从用户那里获取输入目录,检查它是否存在,然后将给定目录中的文件数量与当前目录进行比较并报告其中有更多文件。只要我输入一个子目录,我的代码大部分都可以工作。如果我尝试使用脚本并输入父级或不同分支上的另一个子级,即使给出完整路径,它也无法找到该目录。我知道关于测试命令也提出了类似的问题,但没有一个(我能找到的)解决了当测试无法识别实际上存在的目录时该怎么做。
dir1=$(pwd)
read -rp "Input the path..." dir2
if [ ! -d "$dir2" ]; then
echo "...does not exist"
else
...
...代码的其余部分工作正常。这就是麻烦所在。
编辑:一般的想法是从任何其他目录中查找任何目录,但这并没有发生。例如,从我的 ~/public_html 作为 pwd,如果我运行脚本并输入 ~/schoolwork,甚至完整路径,它无法识别该目录。
我还反转了逻辑(以便我的函数检查它是否存在,然后执行操作,否则返回错误)以及此处发布的方法。结果是一样的。
答案1
您遇到的问题是波形符扩展。如果您~/schoolwork
在脚本的提示符下输入,则开头的波浪号只是另一个字符,当您使用 测试它时,不会扩展到您的主目录的路径[ ! -d "$dir2" ]
。同样,您也无法输入,$HOME/schoolwork
因为变量$HOME
永远不会扩展。
一般来说,提示用户输入路径名是一个坏主意。在命令行上输入路径名要容易得多,在执行脚本或程序之前,波浪号和变量都会展开。此外,在命令行上给出路径名将允许用户使用制表符补全,这反过来又会降低拼写错误的风险。
所以,您希望您的用户使用您的脚本,例如
./script.sh path/to/some/directory
例如,
./script.sh ~/schoolwork
这里,shell 会扩展路径在调用脚本之前,脚本将获得一个路径,/home/turfer/schoolwork
作为其第一个也是唯一的参数。
好的,那么这个脚本该怎么写呢?
这是一个开始的建议:
#!/bin/bash
userdir=$1 # the directory pathname passed on the command line
if [ ! -d "$userdir" ]; then
printf 'Your directory, %s, does not exist\n' "$userdir" >&2
exit 1
fi
现在,我们必须计算当前目录和$userdir
.假设我们真正的意思是任何类型的文件(包括套接字、符号链接、目录ETC。)。
shopt -s dotglob # also match hidden names
herefiles=( ./* )
therefiles=( "$userdir"/* )
如果你只想数常规文件,您将循环遍历这两个模式匹配的内容,并且只考虑通过测试的内容[ -f ... ]
(尽管这仍然会计算到常规文件的符号链接)。
现在我们在两个数组中拥有当前目录和用户指定目录中所有内容的名称。现在我们只需要比较这些数组的长度并说出哪一个是最长的。
if [ "${#herefiles[@]}" -gt "${#therefiles[@]}" ]; then
printf 'There are more files here than in %s\n' "$userdir"
elif [ "${#herefiles[@]}" -lt "${#therefiles[@]}" ]; then
printf 'There are more files in %s than in here\n' "$userdir"
else
printf 'There are an equal number of files here as in %s\n' "$userdir"
fi
您显然也可以手动将文件名存储在两个单独的数组中,而不是数数两个循环中的名称。
答案2
你可以像这样制作你的 shell 脚本:---
#!/bin/bash
read -rp "Input the path..." dir2
dir1=$pwd
#First Check the existence of directory
if [[ -d "$dir2" ]]
then
#If it is a valid directory then count the number of files in each directory
count1=$(find $dir1 -type f | wc -l)
count2=$(find $dir2 -type f | wc -l)
#Compare the number of files in the two directories
if [ $count1 -gt $count2 ]
then
echo "Current Directory has more files"
else if [ $count1 -eq $count2 ]
then
echo "Both Directories have same number of files"
else
echo "Input Directory has greater number of files"
fi
fi
else
#If not a valid directory
echo "Invalid Directory"
fi