Shell recognizes files in ~, but not in ~ / Documents

I take the Unix class, and here is part of my assignment:

For each file and subdirectory in the users // Documents directory, determine whether the item is a file or a directory, and display a message with that name using the file name in the instruction.

So, I wrote the following:

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 

The My Documents directory includes these files and directories:

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

So, I realized that the output should be as follows:

 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 result:

 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 

It seems to me that 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 will be files or directories. This does not work with other paths I tried.

+5
source share
2 answers

Your problem is that ls prints file names without a path.

So your $file gets the values

 DocList.txt Letter mypasswdfile samples things touchfile 

from cycle to cycle.

If your current directory is NOT ~/Documents , testing these file names is incorrect, as it will be a search in the current directory, not the intended one.

The best way to accomplish your task is

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

which will set $file for each full path name needed to find your file.

After that, it should work, but it is very error prone: as soon as your path or one of your files begins to contain a space or other empty character, it will fall to its feet.

Putting " around variables that could potentially contain something with space, etc., is very important. It makes little sense to use a variable without its environment. "

What is the difference?

With [ -f $file ] and file='something with spaces' , [ is called with the arguments -f , something , with , spaces and ] . This, of course, leads to abnormal behavior.

OTOH, with [ -f "$file" ] and file='something with spaces' , [ called with arguments -f , something with spaces and ] .

So quoting is very important in shell programming.

Of course, the same is true for [ -d "$file" ] .

+2
source

The problem is your ls - you treat ls output as absolute, for example. /home/alex/Documents/DocList.txt , but when you do ls ~/Documents , it prints DocList.txt (relative path / file name).

To get the expected absolute behavior, you can use the find instead:

 docs=`find ~/Documents` 

As mentioned in the comments and in another answer, in order to be able to handle spaces in file names, you need to do something like:

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

Source: https://habr.com/ru/post/1207904/


All Articles