如果未安装另一个程序,则运行程序的最佳和快捷方式

0x2*_*fa0 5 scripting bash shell-script

我有这个代码:

#!/bin/bash

num=${1:-undefined}
cmd=$(which {banner,echo} | head -n1)

until [[ "$num" =~ ^[0-9]+$ ]]; do 
    read -p "Type a number: " num
done

for ((num;num>=0;num--)); do
   $cmd $num
   sleep 1
done
Run Code Online (Sandbox Code Playgroud)

但我认为有更好的方法可以知道是否安装了程序。这些我都试过了。但是我认为还不清楚:

  1. which banner && cmd=banner || cmd=echo
  2. cmd=$(eval 'which '{banner,echo}'||' :)
  3. cmd=$(which {banner,echo} | head -n1)
  4. cmd=$(which banner || which echo)

我比其他人更喜欢 3,但是我认为有人可以帮助我找到一个好的方法来做到这一点。我接受使用type,hash或者command如果需要。

这是一个紧凑的代码挑战,所以我想制作一个单行,使其简短,并尽量不重复变量名或任何命令(除了||&&等等)

Jan*_*nis 9

基于函数的方法产生最清晰的代码。至少有两种可能的变体,一种由 FloHimself 在上面的评论中建议的(这不是我的首选方式):

function myprint
{
    if type banner >/dev/null
    then  banner "$@"
    else  echo "$@"
    fi
}

myprint "Hello World!"
Run Code Online (Sandbox Code Playgroud)

或者 - 我更喜欢的变体 - 使用条件函数定义

if type banner >/dev/null
then  function myprint { banner "$@" ;}
else  function myprint { echo "$@" ;}
fi

myprint "Hello World!"
Run Code Online (Sandbox Code Playgroud)

它没有if每次调用的-condition的开销,并且也不需要重复的字符串或变量表达式(如另一个建议)。


ter*_*don 5

最简单的方法就是运行

command1 "hello world" || command2 "hello world"
Run Code Online (Sandbox Code Playgroud)

如果第一个命令不存在,则左侧的命令||将失败,因此将运行右侧的命令。我不明白为什么你需要先测试。就去做吧,如果失败了,就做点别的事。

您可以通过忽略由于缺少命令而导致的错误消息并避免重复字符串来使情况稍微好一些:

string="Hello world!"
banner "$string" || echo "$string"
Run Code Online (Sandbox Code Playgroud)

如果您确实需要检查命令是否存在,我会这样做:

command="banner"
type "$command"  2>/dev/null || command="echo"
"$command" "Hello world!"
Run Code Online (Sandbox Code Playgroud)