I've always developed my shell scripts using parameters, on a daily-basis or even when developing some automation scripts. However, recently I've tried a different approach, exporting environment variables to my scripts.
我总是使用参数开发我的shell脚本,甚至在开发一些自动化脚本的时候。然而,最近我尝试了一种不同的方法,将环境变量导出到脚本中。
#!/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
This ensures a smaller code, easy checks if all the required variables are initialized and also, better understanding of what the script is doing, once all the variables are declared on outside.
这确保了更小的代码、检查是否初始化了所有必需的变量,以及更好地理解脚本正在做什么,一旦所有的变量都在外部声明。
export USER='john' && export FIRST_NAME='John' && export LAST_NAME='Doe' && export EMAIL='john.doe@email.com' && setup_git_account.sh
Which could be represented like this if implemented with receiving parameters:
如果用接收参数实现,则可以这样表示:
setup_git_account.sh --user 'john' --firstname 'John' --lastname 'Doe' --email 'john.doe@email.com'
However, the last one, would need way more lines of code to implement the getopts
switch case, check the passed parameters values, etc.
但是,最后一个,需要更多的代码行来实现getopts开关情况,检查传递的参数值,等等。
Anyway, I know we're used to the second approach, but I think the first approach also has several benefits. And I would like to hear more from you, if there's any downside between the presented approaches. And which one should I be using ?
无论如何,我知道我们已经习惯了第二种方法,但是我认为第一种方法也有一些好处。我想从你们那里听到更多,如果这些方法之间有什么缺点的话。我应该用哪一个呢?
Thanks!
谢谢!
1
None of your values is optional; I would just use positional parameters.
您的值中没有一个是可选的;我只需要使用位置参数。
: ${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"
Providing the way for the user to specify values in an arbitrary order is just an unnecessary complication.
为用户提供以任意顺序指定值的方法只是不必要的麻烦。
You would simply call the script with
您只需调用脚本。
setup_git_account.sh 'john' 'John' 'Doe' 'john.doe@email.com'
Reconsider whether the first and last names need to be separate arguments. They are combined into a single argument to git config
by the script anyway; just take the name as a single argument as well.
重新考虑第一个和最后一个名称是否需要单独的参数。无论如何,它们都通过脚本组合成git config的一个参数;把这个名字作为一个参数。
setup_git_account.sh 'john' 'John Doe' 'john.doe@email.com'
(with the appropriate changes to the script as necessary).
(必要时对脚本进行适当的修改)。
2
A bit off-topic, the invocation syntax with environment variables for bash
can be shorter, no need for export
's:
有点偏离主题,bash的环境变量的调用语法可以更短,不需要导出:
USER='john' FIRST_NAME='John' LAST_NAME='Doe' EMAIL='john.doe@email.com' setup_git_account.sh
0
I never use your approach. I think there are no drawbacks by using parameters. It's a common way to use parameters and if you are using longopts there are self-descriptive. In my opinion env vars are a solution if you need data in different scripts.
我从不使用你的方法。我认为使用参数没有缺点。这是使用参数的一种常见方式,如果您使用longopts,则有自我描述。在我看来,如果您需要不同脚本中的数据,env vars是一种解决方案。
Maybe you have problems to run such a script on systems where you don't be allowed to change the environment.
可能在不允许更改环境的系统上运行这样的脚本可能会有问题。
0
I've parameterized your variables using a guide I wrote a while back and even added --help
.
我用一段时间前写的指导参数化了变量,甚至添加了帮助。
This solution accepts environment variables as well as options (which will trump the variables):
该解决方案接受环境变量和选项(它将胜过变量):
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'"
Note that I changed $USER
to $USER_NAME
to avoid conflicts with your local environment ($USER
is your user name on your local Linux system!)
注意,我将$USER更改为$USER_NAME,以避免与本地环境发生冲突($USER是您本地Linux系统上的用户名!)
You can also extract the user's full name from the system:
您也可以从系统中提取用户的全名:
FULL_NAME="$(getent passwd |awk -v u="$USER_NAME" -F: '$1 == u { print $5 }')"
(I see no reason to separate FIRST_NAME and LAST_NAME; what do you do for Jean Claude Van Damme? They're only used together anyway. Also note that not all users will have full names in the passwd file.)
(我认为没有理由将FIRST_NAME和LAST_NAME分开;你为Jean Claude Van Damme做什么?它们只是在一起使用。还要注意,并不是所有用户在passwd文件中都有全名。
This uses do_help
to show the --help
output. Here's an example of how that could look (I'd put this at the vary top of the script so somebody just reading it can get the synopsis; it's not in the above code block because I wanted to prevent the block from getting a scroll bar):
这使用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 e.g. $EMAIL
Code taken from https://stackoverflow.com/a/41515444/519360
/help
}
本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2017/01/03/1c0c599b6534efefd33982d8d4ea0dd2.html。