讨论/《bash shell 脚本编程经典实例(第 2 版)》 - 19.5 试图修改已导出的变量/
《bash shell 脚本编程经典实例(第 2 版)》 - 19.5 试图修改已导出的变量
共 10 个回复

以下所有的调用脚本sample.sh的操作:

  • bash sample.sh
  • ./sample.sh
  • sh sample.sh
    都是做了两件事:
  1. fork出一个新的shell子进程;
  2. 在新的shell里面执行脚本。

而脚本的环境变量一律都是只对当前shell有效的,在shell退出之后就不复存在(大家可以试试在命令行直接export某个值,重启动shell再运行env看看,会发现这个值没有了)。所以这些新fork出的shell执行完脚本并退出之后,变量自然就丢失了!

如果确实需要保留子脚本里面的变量的话,可以source sample.sh。比如某个工程需要设置到很多环境变量,可以把这些变量放在一个脚本里面,每次需要设置这些变量的时候source这个脚本就行。

4

哈哈哈哈哈哈!老笑话好玩
病人:“医生,我做这个动作的时候会疼。”
医生:“哦,那就别做。”

Take to home message: 不要修改已导出的变量,别做!
非共享、单向通信、爸爸不要儿子给的,就是这么任性。

  1. 导出的环境变量(第二个脚本的VAL不是脚本之间共享的全局变量
  2. 单向的通信形式
    • 导出的环境变量 会被当成调用的组成成分,而一并传递
    • 导出的环境变量 无法再回到父进程
    • 父进程会衍生出大量的子进程,假设每个儿子都给爸爸值,爸爸不知道到底是哪个儿子给的。

Shell学习资料推荐链接搬运

4

就是说会会产生不一样的进程,所以不通用

1

感觉这本书对初学者比较友好,比较清晰,最近在弄iOS/Android编译ImageMagick源码,觉得还是很有帮助的

“那就别做!”

这个解决方案确实出乎意料哈哈哈哈,但是确实就应该这样,如果从大局来看,想让结果稳定且效果好,同时理解起来方便(现在都是团队开发,你的代码不可能只给自己看啦),是需要遵守一定的规则的,哪怕这会导致实现的过程变得复杂。

就像曾经的goto语句一样,虽然跳来跳去感觉很方便,但从后期的维护和代码本身的逻辑理解来看,大部分都是得不偿失,利大于弊。

所以还是如书上所讲,老老实实的设计shell脚本,避免这种问题吧!

学习了

如果“确实需要”第二个脚本更改的变量的值,可以通过source ./second.sh导入脚本内容到当前shell或脚本来执行

   .  filename [arguments]
  source filename [arguments]
         Read and execute commands from filename in the current shell  environ‐
         ment  and  return  the  exit  status of the last command executed from
         filename.  If filename does not contain a slash, filenames in PATH are
         used to find the directory containing filename.  The file searched for
         in PATH need not be executable.  When bash is not in posix  mode,  the
         current  directory  is  searched  if no file is found in PATH.  If the
         sourcepath option to the shopt builtin command is turned off, the PATH
         is not searched.  If any arguments are supplied, they become the posi‐
         tional parameters when filename is executed.  Otherwise the positional
         parameters  are unchanged.  If the -T option is enabled, source inher‐
         its any trap on DEBUG; if it is not, any DEBUG trap  string  is  saved
         and  restored  around  the call to source, and source unsets the DEBUG
         trap while it executes.  If -T  is  not  set,  and  the  sourced  file
         changes  the  DEBUG  trap,  the new value is retained when source com‐
         pletes.  The return status is the status of the  last  command  exited
         within  the script (0 if no commands are executed), and false if file‐
         name is not found or cannot be read.

对哦 应该是 changed so VAL=12

存在一处笔误,19.5.1 脚本结果 changed so VAL=12才对。

知识盲区,这书有看过的朋友觉得作为shell入门合适吗