There is code that should work in bash and zsh. The code snippet lists all directories, sorted by last modified time. He solves this problem quite successfully. The listed directories are generated by the same code and contain only a-zA-Z0-9-_ characters, no spaces.

mcve.sh:

 #!/usr/bin/env bash for i in $(ls -dt1 ./*/); do echo "${i}"; done 

I use shellcheck:

 shellcheck mcve.sh 

I get the following result:

 In mcve.sh line 2: for i in $(ls -dt1 ./*/); ^-- SC2045: Iterating over ls output is fragile. Use globs. 

What is the "fragility" of this method? How can I improve it?

The obvious option "use globy" is not suitable, because need sorting by time.

  • 2
    This was already in the Simpsons :-) That is a detailed answer here: stackoverflow.com/a/938052/5703199 - PinkTux
  • @PinkTux thanks, read) - Nick Volynkin ♦
  • If simply, then, for example, the ab for file name will split into 2 - a and b (yes, @alexander barakin has already answered in detail, and made recommendations better than in the accepted answer) - avp
  • Somewhere I saw a big detailed answer to that topic. - Qwertiy ♦
  • @Qwertiy with us or in English? Won above PinkTux link left. - Nick Volynkin ♦

2 answers 2

The problem is that ls designed primarily to display a list of files in a format that the user can understand. This includes all sorts of labels and other notation, which ls adds to the file names.

ls -1 does not add tags, but this does not eliminate the "colorization". In addition, the operation of ls can vary from the settings of the environment and the operating system, which translates it from the “universal solution” category to the “can work” category.

Also, do not forget that quite often users with the help of alias set default settings for ls .

In order to get a list of files and pass it as parameters to some other command, usually find is used. For example, to get a list of a subdirectory in the current directory, sorted by mtime , you can do something like this:

 find . -maxdepth 1 -type d -printf “%C@ %p\n" | sort | awk '{print $2}' 
  • ls -1 does not add any labels or designations. Can you give an example of the name of the directory where the "fragile" ls really breaks? - Nick Volynkin ♦
  • one
    But in the absence of tags, this does not eliminate the "colorization". In addition, the operation of ls can vary from the settings of the environment and the operating system, which translates it from the “universal solution” category to the “can work” category. - YuS
  • Also, do not forget that quite often users with the help of alias set default settings for ls . - YuS

“fragility” probably meant the processing of special characters that may occur in the names of files / directories. for example, a space:

 $ mkdir "1 2" 3 $ for i in $(ls); do echo "${i}"; done 1 2 3 

while using glob will give the correct result:

 $ for i in *; do echo "${i}"; done 1 2 3 

This problem can be avoided by enclosing the nested command in quotes:

 $ for i in "$(ls)"; do echo "${i}"; done 1 2 3