Передать вывод команды, если она выполнена успешно

Передать вывод команды, если она выполнена успешно
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`

Я хотел выполнить вторую команду ( head -1) только в случае успешного выполнения первой команды. Как мне улучшить эту команду?

решение1

Попробуй это:

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`

Передача xargsфлага -rприведет к запуску только в basenameтом случае, если будет прочитан хотя бы один элемент из стандартного ввода ( head -1).

head -1будет запущен, но вы не увидите и не запишете никаких выходных данных.

Кроме того, если вы не хотите, чтобы пользователь видел какие-либо сообщения об ошибках из ls, вы можете перенаправить lsпоток stderr из /dev/null.

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`

Также обратите внимание, что я добавил кавычки вокруг $MY_DIR. Таким образом, команда не будет выполнена с ошибкой, если $MY_DIRсодержит пробелы.

Если вы используете современную оболочку, например bash, вам следует использовать $( )оболочку захвата вместо обратных кавычек. Вам также следует подумать об изменении стиля ваших переменных. Как правило, вам следует избегать использования в скриптах имен переменных, состоящих только из заглавных букв. Этот стиль обычно зарезервирован для зарезервированных и переменных окружения.

input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)

решение2

В конвейере все команды запускаются и выполняются одновременно, а не одна за другой. Поэтому вам нужно где-то сохранить вывод.

if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
  first_file=$(printf '%s\n' "$ls_output" | head -n 1)
  first_file_name=$(basename -- "$first_file")
fi

Обратите внимание, что предполагается, что имена файлов не содержат символов новой строки. Использование xargsтакже приведет к проблемам с пустыми символами, одинарными и двойными кавычками и обратными косыми чертами. Если оставить переменные без кавычек, возникнут проблемы с пробелами, табуляциями и подстановочными знаками. Если забыть, --возникнут проблемы с именами файлов, начинающимися с -.

Чтобы получить базовое имя самого старого файла без zshкаких-либо ограничений на символы (также избегается проблема ограниченного размера аргументов команды):

 first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))

Если совпадений нет, эта команда не будет выполнена и скрипт будет прерван. Вы также можете сделать:

 first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))

В этом случае first_file_nameмассив будет содержать 1 элемент, если есть совпадение, или 0, если нет. Затем вы можете сделать:

 if (($#first_file_name)); then
    printf 'Match: %s\n' $first_file_name
 else
    echo >&2 No match
 fi

решение3

Найти последний измененный файл в каталоге:

latest() {
  local file path=${1:-.} ext=${2-} latest
  for file in "${path%/}"/*"$ext"; do 
    [[ $file -nt $latest ]] && latest=$file
  done
  [[ $latest ]] && printf '%s\n' "$latest"
}

Использование:latest [directory/path/ [.extension]]

Вместо вызова basenameиспользуйте расширение параметров.

in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}

В каталоге с таким содержимым:

foo.xml bar.xml baz.xml newest.xml

Содержимое переменной base_fn будет следующим:newest

Чтобы использовать это надлежащим образом для достижения цели вашего запроса:

check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
  base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
  printf '%s\n' "No file found in $check_dir" >&2
fi

EDIT: после изучения вопроса я понял, что lsкоманда, о которой идет речь, ищетстарейшийфайл в каталоге. Эту же функцию можно переименовать в oldestи использовать [[ $file -ot $oldest ]] && oldest=$fileвместо этого для достижения того же эффекта. Приносим извинения за возможную путаницу.

Важно отметить, что вы ни при каких обстоятельствах и ни при каких обстоятельствах не должны анализировать вывод ls. никогда.

решение4

Я думаю, что лучшим вариантом здесь будет:

ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
      INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
      echo "Error!"
fi

если файла нет, то код возврата ls равен 2, но если файл найден, то код возврата равен 0.

Связанный контент