我应该使用参数还是导出环境variables?

我总是使用参数来开发我的shell脚本,每天甚至在开发一些自动化脚本的时候。 但是,最近我尝试了一种不同的方法,将环境variables导出到脚本中。

#!/bin/bash : ${USER?"Requires USER"} : ${FIRST_NAME?"Requires FIRST_NAME"} : ${LAST_NAME?"Requires LAST_NAME"} : ${EMAIL?"Requires EMAIL"} set -x setup_git_account(){ su - "${USER}" -c "git config --global user.name '${FIRST_NAME} ${LAST_NAME}'" su - "${USER}" -c "git config --global user.email '${EMAIL}'" } setup_git_account 

这确保了一个较小的代码,容易检查所有必要的variables是否被初始化,并且一旦所有variables在外部被声明,就更好地理解脚本正在做什么。

 export USER='john' && export FIRST_NAME='John' && export LAST_NAME='Doe' && export EMAIL='john.doe@email.com' && setup_git_account.sh 

如果使用接收参数来实现,可以这样表示:

 setup_git_account.sh --user 'john' --firstname 'John' --lastname 'Doe' --email 'john.doe@email.com' 

但是,最后一个,需要更多的代码来实现getopts开关的情况下,检查传递的参数值等。

无论如何,我知道我们习惯了第二种方法,但我认为第一种方法也有好处。 如果在所提出的方法之间有任何不利之处,我想从你那里听到更多。 我应该使用哪一个?

谢谢!

你的任何值都不是可选的; 我只是使用位置参数。

 : ${1?"Requires USER"} : ${2?"Requires FIRST_NAME"} : ${3?"Requires LAST_NAME"} : ${4?"Requires EMAIL"} sudo -u "$1" git config --global user.name "$2 $3" user.email "$4" 

为用户提供以任意顺序指定值的方式只是一个不必要的复杂性。

你可以简单地调用脚本

 setup_git_account.sh 'john' 'John' 'Doe' 'john.doe@email.com' 

重新考虑名字和姓氏是否需要单独的参数。 无论如何,它们被合并到一个单一的参数来通过脚本的git config ; 也只是把这个名字作为一个单一的论点。

 setup_git_account.sh 'john' 'John Doe' 'john.doe@email.com' 

(根据需要对脚本进行适当的更改)。

有点偏离主题,用于bash环境变量的调用语法可以更短,不需要export

 USER='john' FIRST_NAME='John' LAST_NAME='Doe' EMAIL='john.doe@email.com' setup_git_account.sh 

我从来没有使用你的方法。 我认为使用参数没有缺点。 这是使用参数的常用方法,如果您使用的是longopts,则有自描述。 在我看来,如果您需要不同脚本中的数据,env vars是一个解决方案。

也许你有问题在系统中运行这样的脚本,你不能改变环境。

我已经使用我写了一个指导 ,然后添加--help 指南参数化您的变量。

该解决方案接受环境变量以及选项(这将胜过变量):

 while getopts e:f:hl:u:-: arg; do case "$arg" in e ) EMAIL="$OPTARG" ;; f ) FIRST_NAME="$OPTARG" ;; h ) do_help ;; l ) LAST_NAME="$OPTARG" ;; u ) USER_NAME="$OPTARG" ;; - ) LONG_OPTARG="${OPTARG#*=}" case $OPTARG in email=?* ) EMAIL="$LONG_OPTARG" ;; first*=?* ) FIRST_NAME="$LONG_OPTARG" ;; help* ) do_help ;; last*=?* ) LAST_NAME="$LONG_OPTARG" ;; user=?* ) USER_NAME="$LONG_OPTARG" ;; * ) echo "Illegal option/missing argument: --$OPTARG" >&2; exit 2 ;; esac ;; * ) exit 2 ;; # error messages for short options already given by getopts esac done shift $((OPTIND-1)) HELP=" - see ${0##*/} --help" : ${USER_NAME?"Requires USER_NAME$HELP"} : ${FIRST_NAME?"Requires FIRST_NAME$HELP"} : ${LAST_NAME?"Requires LAST_NAME$HELP"} : ${EMAIL?"Requires EMAIL$HELP"} su - "$USER_NAME" -c "git config --global user.name '$FIRST_NAME $LAST_NAME'" su - "$USER_NAME" -c "git config --global user.email '$EMAIL'" 

请注意,我将$USER更改$USER $USER_NAME以避免与您的本地环境发生冲突( $USER是您本地Linux系统上的用户名!)

您也可以从系统中提取用户的全名:

 FULL_NAME="$(getent passwd |awk -vu="$USER_NAME" -F: '$1 == u { print $5 }')" 

(我没有理由将FIRST_NAME和LAST_NAME分开;你对Jean Claude Van Damme做了什么?它们只能一起使用,还要注意,不是所有的用户在passwd文件中都有全名。

这使用do_help来显示--help输出。 下面是一个例子,看起来如何(我把它放在脚本的各个顶部,所以有人刚刚阅读它可以得到大纲;它不在上面的代码块,因为我想阻止块得到滚动条):

 do_help() { cat <</help Usage: ${0##*/} [OPTIONS] -u USER_NAME, --user=USER_NAME -f FIRST_NAME, --firstname=FIRST_NAME -l LAST_NAME, --lastname=LAST_NAME -e EMAIL, --email=EMAIL Each option may also be passed through the environment as eg $EMAIL Code taken from https://stackoverflow.com/a/41515444/519360 /help }