在bash别名中使用filename作为参数,如果不存在则使用默认值

时间:2019-05-27 01:26:21

标签: bash scripting

我正在尝试为命令创建别名,该命令的参数可以是文件名或字符串:

command --style filename.style

OR

command --style "fixed"

有没有一种方法可以将其组合成一个单行,其中我定义了样式参数,例如:

command --style {`find . -name "filename.style"` || "fixed"}

2 个答案:

答案 0 :(得分:1)

在这里,别名不是函数的好选择,因为它们没有分支逻辑支持(没有跳过基本要分配函数的箍)。最好直接使代码成为函数:

foostyle() {
  if [[ -e filename.style ]]; then
    foo --style filename.style "$@"
  else
    foo --style fixed "$@"
  fi
}

...如果当前工作目录中存在foostyle whatever,则foo --style filename.style whatever将运行filename.style,否则将运行foo --style fixed whatever

据我所知,这就是您要的。

答案 1 :(得分:1)

  1. 动机和动机

@CharlesDuffy已经详细警告过,他的警告不应掉以轻心。

此答案将是最错误的方法,以尽可能最正确的方式进行错误操作,并尝试解决所提出的问题。

  1. 请求和要求

在本练习中,我们要创建一个别名,该别名的参数可以是文件名或字符串。

  1. 在一开始

参考了某些command,出于此响应的目的,我们将假定:

$ which command
/usr/bin/command
  1. 查找文件或为$f定义

理想情况下,我们应该知道找到filename.style的完整路径,但是将假定搜索是唯一的选择。强烈建议在启动时或作为cron服务一次执行这些类型的任务,并将解析后的值分配给环境变量。

findls产生的输出应仅考虑用于交互式维护目的not for use in scripts。 BASH 4+脚本中首选的目录遍历方法是globstar,我们将在这些示例中使用它。

激活globstar并选择在启动脚本中找到文件,即。 ~/.bashrc ~/.profile等。

# activating globstar is not is required for these examples
shopt -s globstar


# optionally search and find filename.style once on startup
for f in **/filename.style; do
    break;
done
if [ ! -e $f ]; then
    f=fixed;
fi
export FILENAME_STYLE="$f";
# Use $FILENAME_STYLE to construct a simple alias
# alias command='/usr/bin/command $FILENAME_STYLE'

在此讨论中,我们将忽略文件搜索的开销,以说明别名实现中的复杂功能。以下命令将expand the glob并为$f定义:

f=(**/filename.style)

如果发现多个文件,则仅将索引0用作$f == ${f[0]}

  1. 验证$f是否存在或分配字符串"fixed"

我们仅担心$f不存在,使用内置的BASH test表达式! -e $f将提供真实性,请参见man test for details

一种快捷,肮脏的速记方法是使用also frowned uponAND_IF &&,因为它的行为与if..then..else..fi不同,并且可能会产生不需要的结果。这些警告不应该被轻易接受,如果您只有99%的把握,那就输入8个额外的字符并放心。

[[ ! -e $f ]] && f=fixed;

首选方法:

if [ ! -e $f ]; then f=fixed; fi;
  1. 使用别名或代替功能

关于优缺点的讨论已经足够,我们将重点介绍实现上的差异。

别名是避免输入长命令或始终重复相同选项的简单快捷方式。它不能接受参数,而是将它们附加在后面,并且应将其设计为具有相应功能。

alias command='f=(**/filename.style); [[ ! -e $f ]] && f=fixed; /usr/bin/command "$f"';

或:

alias command='f=(**/filename.style); if [ ! -e $f ]; then f=fixed; fi; /usr/bin/command "$f"';

函数确实接受参数,因此不能将其附加到参数上,并应进行相应的工程设计以适当地转发参数。这些示例有意地镜像了别名实现以帮助进行比较。

command() { f=(**/filename.style); [[ ! -e $f ]] && f=fixed; /usr/bin/command "$f" "$@"; }

或:

command() { f=(**/filename.style); if [ ! -e $f ]; then f=fixed; fi; /usr/bin/command "$f" "$@"; }
  1. 结论

在所有这些示例中,command可以为$f进行定义,测试其有效性并为/usr/bin/command分配适当的参数,同时仍然可以接受其他命令行参数:

command arg1 arg2 arg3

我们已经创建了满足要求的工作别名和功能函数。比较实现上的差异,命令行参数处理的注意事项,即使我们应该避免昂贵的开销,仍然可以为别名和函数添加丰富的功能。

nJoy!