Linux 我应该使用参数还是导出环境变量?

Linux 我应该使用参数还是导出环境变量?,linux,bash,shell,Linux,Bash,Shell,我总是使用参数开发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 - "${US

我总是使用参数开发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
这确保了代码更小,易于检查是否所有必需的变量都已初始化,并且在外部声明所有变量后,能够更好地理解脚本正在执行的操作

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
开关用例,检查传递的参数值,等等

无论如何,我知道我们已经习惯了第二种方法,但我认为第一种方法也有一些好处。如果所介绍的方法之间存在任何不利之处,我希望从您那里听到更多信息。我应该用哪一种


谢谢

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


在不允许您更改环境的系统上运行这样的脚本可能会有问题。

有点离题,对于
bash
的带有环境变量的调用语法可以更短,不需要
导出

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

你的价值观没有一个是可选的;我只会使用位置参数

: ${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'

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

我已经使用我不久前编写的一个脚本参数化了您的变量,甚至添加了
--help

此解决方案接受环境变量和选项(这将胜过这些变量):

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

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

FULL_NAME="$(getent passwd |awk -v u="$USER_NAME" -F: '$1 == u { print $5 }')"
(我认为没有理由将名字和姓氏分开;你为Jean-Claude Van Damme做了什么?它们只是一起使用。还要注意,并非所有用户的passwd文件中都有全名。)

这使用
do\u help
来显示
--help
输出。下面是一个这样的例子(我把它放在脚本的顶部,这样只要有人阅读它就可以得到概要;它不在上面的代码块中,因为我想阻止该块获得滚动条):


do_help(){cat对于环境变量,如果不是所有变量都被显式设置,那么发生意外行为的可能性显然更高。可以(意外地)设置它们系统、bashrc、以前运行的脚本等。我建议使用参数使用小写变量名。
USER
,尤其是,已经在使用,并且将在您的环境中设置。如果所有实用程序都使用环境变量而不是参数,这将是设计的一个主要缺点:如果两个实用程序使用相同的变量名,比如说
foo
;如果你调用第一个变量,比如
foo=bar utility1
,然后
utility1
需要调用
utility2
而不调用
foo
,那么
utility1
就需要取消设置
foo
。虽然
utility1
可以处理自己的变量,但是如果
utility1
可以处理自己的变量,事情会变得更棘手>utility1
不知道,
utility2
也会调用
utility3
,该函数使用的变量
baz
也被
utility1
使用。这将是一场噩梦!当前的设计更安全,因为它提供了一些隔离。链接实用程序也会更困难。
find
您会处理
find…\(-sometest-exec实用程序1-someoption{}\)-o\(-someothertest-exec实用程序1-someotheroption{}\)
。这是一个很好的答案。环境变量与参数的问题有点基于观点,但如果使用环境变量,这是调用脚本的正确方法。太好了!非常感谢您的回答!
FULL_NAME="$(getent passwd |awk -v u="$USER_NAME" -F: '$1 == u { print $5 }')"