Bash:如果要修改脚本,请添加内联

Bash:如果要修改脚本,请添加内联,bash,scripting,Bash,Scripting,我正在编写一个bash脚本,其中我需要根据参数执行两个不同的操作 例如,在没有参数(/script)的情况下调用我的脚本,它应该执行以下操作: docker编写运行… 如果我向脚本(/script-d)发送一个参数,它应该执行以下操作: docker compose-f文件运行… 因此,-f文件是唯一基于参数添加的部分。我不想在每个if语句中重复整个代码,有没有更好的方法?处理args的方法很多(包括getopts),但最简单的是 #!/bin/bash # by default, set t

我正在编写一个bash脚本,其中我需要根据参数执行两个不同的操作

例如,在没有参数(
/script
)的情况下调用我的脚本,它应该执行以下操作:

docker编写运行…

如果我向脚本(
/script-d
)发送一个参数,它应该执行以下操作:

docker compose-f文件运行…


因此,
-f文件
是唯一基于参数添加的部分。我不想在每个if语句中重复整个代码,有没有更好的方法?

处理args的方法很多(包括
getopts
),但最简单的是

#!/bin/bash

# by default, set to none; otherwise, set to some value
[ "$1" = "-d" ] && args="-f file" || args=

docker-compose $args run ...

一种选择是使用数组。如果存在
-d
,则将
-f“$file”
添加到数组中

args=()
[[ $1 == -d ]] && args+=(-f "$file")
docker-compose "${args[@]}" run...
另一种方法是仅在设置变量时使用
:+
替换替代值。如果
$option
设置为
-d
,则替换为
-f“$file”
;如果是空的,那就让它空着

option=
[[ $1 == -d ]] && option=-d
docker-compose ${option:+-f "$file"} run...

这两个选项都将正确处理包含空格的文件名。

解析参数的方法很多。
测试
(或
[
)是最简单的方法,但如果可能存在多种情况,则最好使用
案例
语句:

#!/usr/bin/env bash

case "$1" in;
  -d) args=( -f "file" ) ;;
  "") args=() ;;
  *) echo "Usage error." >/dev/null; exit 1 ;;
esac

docker-compose "${args[@]}" run
对于更大规模的选项处理,
getopts
可能是一种方法:

#/usr/bin/env bash

args=()
while getopts hdf: opt; do
  case "$opt" in
    h) printf "Usage: ${0##*/} [-d]"; exit 0 ;;
    d) args=( -f "file" ) ;;       # use a static file
    f) args=( -f "$OPTARG" ) ;;    # use a user-specified file
  esac
done
shift $((OPTIND - 1))

docker-compose "${args[@]}" run

有关用法信息,请在“SHELL内置命令”部分中搜索
getopts

,如果您添加了任何参数,或者您专门添加了
-d
文件是否为硬编码字符串,或者是否为
-d
标志的参数?硬编码字符串请勿使用常规参数来表示单词列表。。。。(扩展@chepner的评论)除非您担心可移植性,可能会在不支持数组的shell中运行脚本。即使如此,我也不建议这样做。在可移植shell中,没有特别安全的方法来建立参数列表。我会将公共部分抽象为函数(例如,
dc\u run(){docker compose“$@”run;}
),然后根据需要对
dc_run
进行不同的调用。跨bash版本的数组可能会有问题(对于那些不只是使用linux的版本),例如aix、solaris、z/OS(奇怪的是,尤其是solaris)。默认情况下,我的大多数脚本都不受后期Bashism的影响,除非它是一个长/复杂的脚本,并且实际上只适用于linux。OP没有指定
文件
是什么,所以这个答案不必费心猜测。请更正使用
“$@”
正确处理扩展是一个好主意(我赞成函数等等)……但这是留给读者的练习,或者是一个单独的问题。