Bash:如何确定变量是在命令中设置的还是在父级中导出的

  • 本文关键字:命令 何确定 变量 Bash 设置 bash
  • 更新时间 :
  • 英文 :


是否有以bash为中心的方法来判断环境变量是在父shell的命令行上设置的,还是事先导出的?

例如,从my_script.sh中,我们可以区分变量A是通过方法1还是方法2:设置的吗

  1. A=1 ./my_script.sh
  2. export A=1; ./my_script.sh

注意:为了简单起见,我们假设父shell是bash,my_script.sh的解释器也是bash

这样做肯定有点困难,因为从./my_script.sh的角度来看,envvar完全相同。但是,您可以使用extdebugDEBUG陷阱和$BASH_COMMAND来查看运行的命令,它似乎也包括变量赋值。。。

$ shopt -s extdebug
$ trap 'export CMDLINE=$BASH_COMMAND' DEBUG
$ env |grep CMDLINE
CMDLINE=env
$ foo=bar env |grep CMDLINE
CMDLINE=foo=bar env

你仍然需要解析字符串来获取赋值,如果可以有多个赋值(例如foo='some strings'"$(comm subst)" this too A=1 ./myscript.sh(,那么这可能很难正确

但对于简单的情况,仅仅寻找一个领先的A=可能是可行的。

在某些情况下,您可以知道与此脚本的区别:

#!/usr/bin/env bash

echo "in test.sh's environment, A=$A"
mapfile -d "" environ < /proc/$PPID/environ
for item in "${environ[@]}"; do
test "${item#A=}" = "$item" || { echo "[$item] is in parent's initial environment."; exit; }
done
echo "A is not in parent's initial environment."
~/tmp$ unset A; bash
~/tmp$ A=1 ./test.sh
in test.sh's environment, A=1
A is not in parent's initial environment.
~/tmp$ 
~/tmp$ A=1 bash
~/tmp$ ./test.sh
in test.sh's environment, A=1
[A=1] is in parent's initial environment.

问题是/proc/pid/environ不是动态的。因此脚本无法捕获export A=1的情况

简短回答:

现在您可以验证与命令内联导出的变量和由导出命令导出的变量之间没有语义差异:

  • 内联测试:
$ unset A
$ A='hello inline export' bash -c 'declare -p A'
declare -x A="hello inline export"
  • 测试导出命令:
$ unset A
$ A='hello export'
$ export A
$ bash -c 'declare -p A'
declare -x A="hello export"

在这两种情况下,bash都将变量视为declare -x A=...,这是导出变量的正常声明。

最新更新