Вы можете повторить имя, если grep не совпадает:
$ for i in cindrella daniel polo; do grep -q "$i" test.txt || echo "$i"; done
cindrella
daniel
-q
тихий режим, выход после обнаружения любого совпадения
Честно говоря, я не знаю, что вы пытаетесь сделать с этими чеками. Если вам нужно проверить, доступна ли хотя бы одна из этих программ:
programs=(fzf rofi dmenu)
available=()
for prog in "${programs[@]}"; do
location=$(type -P $prog) && available+=("$location")
done
(( ${#available[@]} == 0 )) && die "none of ${programs[*] are available"
# what is your logic for choosing one if multiple are available?
menu=${available[0]}
Судя по вашим комментариям, будет чище переместить больше работы в ветки кейсов:
fzf_exists=0
rofi_exists=0
dmenu_exists=0
# reorder these if you want: the _last_ one to succeed is the default
if command_exists dmenu; then
dmenu_exists=1
menu_default=$dmenu_cmd
fi
if command_exists rofi; then
rofi_exists=1
menu_default=$rofi_cmd
fi
if command_exists fzf; then
fzf_exists=1
menu_default=$fzf_cmd
fi
if [[ -z $menu_default ]]; then
die "none of fzf, rofi, dmenu are available"
fi
while true; do
case "$1" in
-f|--fzf)
(( fzf_exists )) || die "fzf is not available"
[[ -n $menu ]] && die "choose only one of fzf/rofi/dmenu"
menu=$fzf_cmd
shift
;;
-r|--rofi)
(( rofi_exists )) || die "rofi is not available"
[[ -n $menu ]] && die "choose only one of fzf/rofi/dmenu"
menu=$rofi_cmd
shift
;;
-d|--dmenu)
(( dmenu_exists )) || die "dmenu is not available"
[[ -n $menu ]] && die "choose only one of fzf/rofi/dmenu"
menu=$dmenu_cmd
shift
;;
#...
esac
done
: ${menu:=$menu_default}
Обратите внимание, что функция command_exists
должна return 1
неexit 1
Если предполагается, что пользователь должен выбрать только одну из многих, я бы просто использовал одну переменную для сохранения выбора, отбрасывая переменные опции per -. В любом случае, нас не интересуют все комбинации, нам просто нужен один вариант из трех, а другой — «не установлен/по умолчанию».
Так:
#!/bin/sh
cmd= # empty value for default
case "$1" in
--rofi|-r) cmd=rofi ;;
--fzf|-f) cmd=fzf ;;
--dmenu|-d) cmd=dmenu ;;
esac
if [ -z "$cmd" ]; then
echo "no command set, looking for default"
if command_exists fzf; then
cmd=fzf
elif
...
fi
fi
echo "running with command $cmd"
# actually do something
Здесь выбранный режим сохраняется в cmd
. На самом деле я даже не дал пользователю возможность дать две команды, для флага читается только первый аргумент. Теперь, если вы используете getopt
или getopts
, это на самом деле не работает, но мы могли бы проверить, был ли уже установлен режим, прежде чем снова установить его ().
#!/bin/sh
error_if_cmd_set() {
if [ -n "$1" ]; then
echo "command already set"
exit 1
fi
}
cmd=
for arg in "$@"; do
case "$1" in
--rofi|-r) error_if_cmd_set "$cmd"; cmd=rofi ;;
--fzf|-f) error_if_cmd_set "$cmd"; cmd=fzf ;;
--dmenu|-d) error_if_cmd_set "$cmd"; cmd=dmenu ;;
esac
done
#...
echo "using command $cmd"