Bash: подчиненное поведение ls

Мне интересно, почему я не получаю такой же вывод от:

ls -1 -tF | head -n 1

а также

echo $(ls -1 -tF | head -n 1)

Я пытался получить последний измененный файл, но используя его внутри вложенной оболочки, иногда я получаю более одного файла в результате?

Почему этого и как избежать?

2 ответа

Проблема возникает из-за того, что вы используете нецитированную подоболочку и -F флаг для ls выводит специальные символы оболочки, добавляемые к именам файлов.

-F, --classify
добавить индикатор (один из */=>@|) в записи

К исполняемым файлам добавляется *.

Когда ты бежишь

echo $(ls -1 -tF | head -n 1)

затем

$(ls -1 -tF | head -n 1)

вернет имя файла, и если это будет исполняемый файл, а также будет префиксом для другого файла, то он вернет оба.

Например, если у вас есть

test.sh
test.sh.backup

тогда он вернется

test.sh*

который при отражении расширяется до

test.sh test.sh.backup

Цитирование подоболочки предотвращает это расширение

echo "$(ls -1 -tF | head -n 1)"

возвращается

test.sh*

Я только что нашел ошибку: если вы используете echo $(ls -1 -tF | head -n 1)механизм перетаскивания файлов может привести к дополнительным совпадениям.

Так echo "$(ls -1 -tF | head -n 1)" бы избежать этого.

Потому что, если результатом является исполняемый файл, он содержит * в конце.

Я попытался поместить причину -F в комментарии, но теперь я решил поместить это здесь:

Я добавил следующие строки в мой.bashrc, чтобы иметь ярлык для отображения последних измененных файлов или каталогов:

function L {
  myvar=$1; h=${myvar:="1"};
  echo "last ${h} modified file(s):"; 
  export L=$(ls -1 -tF|fgrep -v / |head -n ${h}| sed 's/\(\*\|=\|@\)$//g' );    
  ls -l $L;
}
function LD {
  myvar=$1;
  h=${myvar:="1"};
  echo "last ${h} modified directories:"; 
  export LD=$(ls -1 -tF|fgrep / |head -n $h | sed 's/\(\*\|=\|@\)$//g'); ls -ld $LD;
}
alias ol='L; xdg-open $L'
alias cdl='LD; cd $LD'

Так что теперь я могу использовать L (или L 5), чтобы перечислить последние (последние 5) измененные файлы. Но не каталоги.

И с L; jmacs $L I Я могу открыть мой редактор, чтобы отредактировать его. Традиционно я использовал свой псевдоним lt='ls -lrt', но потом мне пришлось набрать имя заново...

Теперь после mkdir ... я использую cdl для перехода на этот каталог.

Другие вопросы по тегам