我正在编写一个Shell脚本,用于读取一个包含键值对的文件,并将这些变量设置为环境变量。但是我有一个疑问,如果我执行source file.txt
,是否会将该文件中定义的变量设置为环境变量,还是应该逐行读取文件并使用export命令进行设置?
在这种情况下,source命令和export命令是否不同?
当你source
这个文件时,变量将被设置但是除非设置了allexport
选项,否则变量不会被导出。如果你想要导出所有的变量,使用allexport
并且source
这个文件比读取文件并显式地使用export
更加简单。换句话说,你应该这样做:
set -a
. file.txt
我更喜欢使用.
,因为它比source
更易移植,但在bash
中source
同样有效。
请注意,导出变量并不会使其成为环境变量,它只会在任何子shell中成为环境变量。
setenv
函数来将变量放入环境中,但并非所有shell都提供该功能。 - William Pursellexport
和source
(.
)的额外解释和示例,我认为这非常有用,链接在这里:https://dev59.com/2mUp5IYBdhLWcg3wJlAH#62626515。我自己很长时间没有编写bash脚本后,总是忘记这些东西的含义,因此我将我的答案称为“规范化”的答案,这意味着每次我忘记细节或需要刷新时,我都计划再次回到这个答案。 - Gabriel Staplessource
(.
)与export
(以及最后还有一些文件锁[flock
]的内容)的区别source some_script.sh
,或者POSIX兼容的等效方式. some_script.sh
,从其他脚本中引入变量,而export my_var="something"
将变量传递给从当前脚本/进程调用/启动的其他脚本/进程。在Linux shell脚本中使用source some_script.sh
或. some_script.sh
有点像在Python中使用import some_module
,或者在C或C++中使用#include <some_header_file.h>
。它从被引用的脚本中引入变量。
使用export some_var="something"
有点像在本地设置该变量,以便在当前脚本或进程的其余部分中可用,并且同时将其传递给从此处开始调用的所有子脚本或进程。
所以,这个:
# export `some_var` so that it is set and available in the current
# script/process, as well as in all sub-scripts or processes which are called
# from the current script/process
export some_var="something"
# call other scripts/processes, passing in `some_var` to them automatically
# since it was just exported above!
script1.sh # this script now gets direct access to `some_var`
script2.sh # as does this one
script3.sh # and this one
# set this variable for the current script/process only
some_var="something"
# call other scripts/processes, passing in `some_var` to them **manually**
# so they can use it too
some_var="something" script1.sh # manually pass in `some_var` to this script
some_var="something" script2.sh # manually pass in `some_var` to this script
some_var="something" script3.sh # manually pass in `some_var` to this script
export some_var="something"
,实际上是将变量递归传递或导出给子进程,因此如果我们从当前脚本/进程内部调用script1.sh
,那么script1.sh
将会从当前脚本中获取导出的变量,如果script1.sh
调用script5.sh
,而script5.sh
又调用script10.sh
,那么这两个脚本也会自动获取导出的变量。这与上面手动设置变量的情况形成对比,在手动设置变量的情况下,只有显式调用并设置变量的脚本才会获取它们,因此子脚本不会自动从调用脚本中获取任何变量!unset
将“取消导出”,如下所示:# set and export `some_var` so that sub-processes will receive it
export some_var="something"
script1.sh # this script automatically receives `some_var`
# unset and un-export `some_var` so that sub-processes will no longer receive it
unset some_var
script1.sh # this script does NOT automatically receive `some_var`
源
或。
导入。导出
导出。取消设置
取消导出。创建此脚本:
source_and_export.sh:
#!/bin/bash
echo "var1 = $var1"
var2="world"
chmod +x source_and_export.sh
source
(.
) 和 export
命令。输入你在以$
开头的行后面看到的命令(不包括注释)。其他行是输出结果。按顺序逐个运行这些命令:$ echo "$var1" # var1 contains nothing locally.
$ var1="hello" # Set var1 to something in the current process
# only.
$ ./source_and_export.sh # Call a sub-process.
var1 = # The sub-process can't see what I just set var1
# to.
$ export var1 # **Export** var1 so sub-processes will receive it.
$ ./source_and_export.sh # Call a sub-process.
var1 = hello # Now the sub-process sees what I previously set
# var1 to.
$ echo "$var1 $var2" # But, I (my terminal) can't see var2 from the
# subprocess/subscript.
hello
$ . ./source_and_export.sh # **Source** the sub-script to _import_ its var2
# into the current process.
var1 = hello
$ echo "$var1 $var2" # Now I CAN see what the subprocess set var2 to
# because I **sourced it!**
hello world # BOTH var1 from the current process and var2 from
# the sub-process print in the current process!
$ unset var1 # Unexport (`unset`) var1.
$ echo "$var1" # var1 is now NOT set in the current process.
$ ./source_and_export.sh # And the sub-process doesn't receive it either.
var1 =
$ var1="hey" # Set var1 again in the current process.
$ . ./source_and_export.sh # If I **source** the script, it runs in the
# current process, so it CAN see var1 from the
# current process!
var1 = hey # Notice it prints.
$ ./source_and_export.sh # But if I run the script as a sub-process, it can
# NOT see var1 now because it was `unset`
# (unexported) above and has NOT been `export`ed
# again since then!
var1 = # So, var1 is not exported to the subprocess.
$
有时候,在编写脚本来启动程序等操作时,我会遇到 export
似乎无法正常工作的情况。在这种情况下,有时候必须将文件本身用作全局变量,以传递信息从一个程序到另一个程序。以下是如何完成这一操作的示例。在本示例中,文件 ~/temp/.do_something
的存在会被用作进程间的布尔变量:
# ------------------------------------------------------------------------------
# In program A, if the file "~/temp/.do_something" does NOT exist,
# then create it
# ------------------------------------------------------------------------------
mkdir -p ~/temp
if [ ! -f ~/temp/.do_something ]; then
touch ~/temp/.do_something # create the file
fi
# ------------------------------------------------------------------------------
# In program B, check to see if the file exists, and act accordingly
# ------------------------------------------------------------------------------
mkdir -p ~/temp
DO_SOMETHING="false"
if [ -f ~/temp/.do_something ]; then
DO_SOMETHING="true"
fi
if [ "$DO_SOMETHING" == "true" ] && [ "$SOME_OTHER_VAR" == "whatever" ]; then
# remove this global file "variable" so we don't act on it again
# until "program A" is called again and re-creates the file
rm ~/temp/.do_something
do_something
else
do_something_else
fi
flock
命令:https://man7.org/linux/man-pages/man1/flock.1.html。还可以参考man flock
或man 1 flock
。man 2 flock
。在您的C文件中,您必须#include <sys/file.h>
以使用此函数。bash
文件夹下:https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world关于“如何在Bash中编写、导入、使用和测试库”的个人网站文章
这篇文章更多地讨论了使用“.”操作符引用文件以及如何通过使用类似Python的特殊魔法使文件不会在引用时运行:
if [ "$__name__" = "__main__" ]; then
main "$@"
fi
我的回答在从shell脚本导入函数
import
和 #include
以及“将其传递给从此处调用的任何和所有子脚本或进程”确实有助于澄清这个概念! - slow-but-steadyexport
的作用,以及什么时候应该使用它,以及如何将变量传递给正在调用的脚本感到困惑--而我在自己的回答中找到了答案!例如:some_var="something" script1.sh #手动将 'some_var' 传递给此脚本
。 - Gabriel Staples
rm -rf ${HOME}
(或更糟的)这行命令... - johnsyweb