简体   繁体   English

Shell识别〜而不是〜/ Documents中的文件

[英]Shell recognizes files in ~ but not in ~/Documents

I'm taking a Unix class, and here's a part of my assignment: 我正在上Unix类,这是我的作业的一部分:

For each file and subdirectory in the user's ~/Documents directory, determine if the item is a file or directory, and display a message to that effect, using the file name in the statement. 对于用户的〜/ Documents目录中的每个文件和子目录,请确定该项目是文件还是目录,并使用语句中的文件名显示相应的消息。

So, what I have written is this: 所以,我写的是这样的:

docs=`ls ~/Documents`

for file in $docs ; do
    if [ -f $file ] ; then
        echo $file "is a file."
    elif [ -d $file ] ; then
        echo $file "is a directory."
    else
        echo $file "is not a file or directory."
    fi
done

My Documents directory includes these files and directories: 我的文档目录包括以下文件和目录:

DocList.txt  (file)
Letter       (file)
mypasswdfile (file)
samples      (directory)
things       (directory)
touchfile    (file)

So I figured that the output should be this: 所以我想输出应该是这样的:

DocList.txt is a file.
Letter is a file.
mypasswdfile is a file.
samples is a directory.
things is a directory.
touchfile is a file.

However, this is the output: 但是,这是输出:

DocList.txt is not a file or directory.
Letter is not a file or directory
mypasswdfile is not a file or directory
samples is not a file or directory
things is not a file or directory
touchfile is not a file or directory

I feel like I should mention that if I set the $docs variable to `ls ~' it will successfully display the contents of my home directory and whether the items are files or directories. 我想我应该提一下,如果将$ docs变量设置为`ls〜',它将成功显示主目录的内容以及项目是文件还是目录。 This does not work with other paths I have tried. 这不适用于我尝试过的其他路径。

The problem is your ls command - you're treating the output of ls as absolute eg /home/alex/Documents/DocList.txt , but when you do ls ~/Documents it prints out DocList.txt (a relative file path / name). 问题是您的ls命令-您将ls的输出视为绝对,例如/home/alex/Documents/DocList.txt ,但是当您执行DocList.txt ls ~/Documents它将输出DocList.txt (相对文件路径/名称)。

To get the expected absolute behaviour you can use the find command instead: 要获得预期的绝对行为,可以使用find命令代替:

docs=`find ~/Documents`

As mentioned in the comments and in another answer, to also be able to handle whitespace in filenames you need to do something like: 如评论和另一个答案中所述,要能够处理文件名中的空格,您需要执行以下操作:

docs=( ~/Documents/* )
for f in "${docs[@]}"; do
    ...

Your problem is that ls only outputs the file names without path. 您的问题是ls仅输出不带路径的文件名。

So your $file gets the values 所以你的$file得到值

DocList.txt
Letter
mypasswdfile
samples
things
touchfile

from loop run to loop run. 从循环运行到循环运行。

If your current directory is NOT ~/Documents , testing these file names is wrong, as this would search in the current directory and not in the intended one. 如果您的当前目录不是~/Documents ,则测试这些文件名是错误的,因为这将在当前目录中搜索而不是在预期目录中搜索。

A much better way to accomplish your task is 完成任务的更好方法是

for file in ~/Documents/* ; do
    ...
done

which will set $file to each of the full path names needed to find your file. 这会将$file设置$file查找文件所需的每个完整路径名。

After doing so, it should work, but it is very error prone: once your path or one of your files starts having a space or other blank character in it, it will fall on your feet. 这样做之后,它应该可以工作,但是很容易出错:一旦路径或文件之一开始包含空格或其他空白字符,它就会落在您的脚上。

Putting " around variables which can potentially contain something with a space etc. is quite essential. There is almost no reason ever to use a variable without its surrounding " . "放在可能包含空格等东西的变量周围非常必要。几乎没有理由在没有变量的情况下使用变量"

What is the difference here? 这里有什么区别?

With [ -f $file ] , and file='something with spaces' , [ is called with the arguments -f , something , with , spaces and ] . 使用[ -f $file ]file='something with spaces'[将使用-fsomethingwithspaces]参数调用。 This surely leads to wrong behaviour. 这肯定会导致错误的行为。

OTOH, with [ -f "$file" ] , and file='something with spaces' , [ is called with the arguments -f , something with spaces and ] . OTOH,带有[ -f "$file" ]file='something with spaces'[被称为-fsomething with spaces]

So quoting is very essential in shell programming. 因此,引用在Shell编程中非常重要。

Of course, the same holds for [ -d "$file" ] . 当然, [ -d "$file" ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM