shell-子进程

最近写shell脚本,发现了许多之前没搞懂的东西。就比如说子程序这个问题,以为自己弄懂了,但是写脚本才发现自己没搞懂。

COLUMNS变量问题

第一个问题就是这个$COLUMNS变量问题,之前写了一个类似的脚本,需要计算当前终端的宽度,然后动态调整显示的宽度。当时是使用tput colstput lines来获取终端的宽高的。后来发现$COLUMNS$LINES可同样可以获取这些值,所以这次打算使用这个来写,结果就是程序报错了,后来才发现是这个变量没能获取到值。

我就很奇怪了,明明在终端可以执行的命令为什么不能在脚本中执行了。后来才知道这两个变量并不是环境变量,而是说它是某些shell才会开启的功能。它是动态计算的,而且只能在当前使用的shell中才行,并不能用做shell在后台执行。

所以如果要在脚本中获取这个变量的话就还是使用tput吧

1
2
tput lines
tput cols

子进程问题

之前写脚本时,如果涉及到目录移动的话,也没太在意,因为最后我总是会加上cd -来回到之前的目录。所以这次真的想写个脚本来改变当前shell的目录时才发现这并不行。虽然我知道子进程这个知识,但是还是算没弄清楚吧。

如果运行一个脚本的话,那么就会在当前shell下fork一个子shell,而在子shell中的操作并不会影响到当前的shell。

这也就是说我们在shell中指定的变量,即使是使用了export也不会在当前shell中有值,也就是说子进程不会影响父进程。但是反过来却可以,父进程会影响子进程,比如父进程中的变量就会传入子进程,这点也需要注意,在以后写shell脚本时,如果设计到比较通用变量名(比如i)的话,还是要先unset一下才行。

如果非要做到这个功能的话(使用脚本来改变当前shell的目录),也是可以做到的,那么就需要使用source这个命令,它会将子shell的命令拿来在当前shell中运行,这是它的一个很重要的功能。不仅如此,它还可以会影响其父进程,所以说全部都会受到影响。这也是为什么我们修改了.bashrc等初始化的文件后source一下就可以的原因。之前无脑使用source命令很多次了,但是却没有发现其真正作用。就好比我最常用的source .Xresources命令,用来重新加载urxvt和xterm配置。