Как `команда file.txt ИЛИ another_file.txt` в CLI (bash / zsh) - PullRequest
0 голосов
/ 07 января 2020

Можно ли выполнить команду с file.txt в качестве аргумента или, если file.txt не существует, с another_file.txt?

Чтобы сделать мой запрос более реалистичным c, Я хотел бы запустить VSCode с файлом рабочей области по умолчанию или, если файл рабочей области не существует, с . (текущая папка), что-то вроде:

code *.code-workspace OR .

Если существует *.code-workspace, то команда должна быть эквивалентна code *.code-workspace, в противном случае, комментарий должен быть эквивалентен code .

Возможно ли это в bash или zsh? (Я использую zsh + oh-my-zsh)

1 Ответ

3 голосов
/ 07 января 2020

В bash вы можете использовать nullglob для расширения подстановочных знаков (например, *) до нуля, если совпадений нет. Затем поместите все в массив и получите первую запись. Обратите внимание, что $array совпадает с первой записью массива ${array[0]}.

#! /bin/bash
shopt -s nullglob
files=(*.code-workspace .)
code "$files"

Над кодом начинается code firstMatchOf.code-workspace, если есть файл, заканчивающийся .code-workspace и ., если нет такой файл.

Для zsh вы можете сделать то же самое, заменив shopt -s nullglob на setopt null_glob.

Обратите внимание, что описанный выше подход работает только с подстановочными знаками. files=(a b); code "$files" вызовет code a, даже если a не существует. Здесь вы можете использовать следующую функцию вместо этого, которая должна работать в каждом случае:

#! /bin/sh
firstExisting() {
    set -- "$@" . # ensure termination 
    while ! [ -e "$1" ]; do
        shift
    done
    printf %s\\n "$1"
}

Пример использования:

code "$(firstExisting *.code-workspace .)"

или просто

code "$(firstExisting *.code-workspace)"

… as . является значением по умолчанию, если ни один из аргументов не существовал. shopt -s nullglob здесь не нужен.

...