mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-24 02:20:09 +08:00
Merge pull request #11652 from HankChow/master
翻译完成 20181205 Bash Variables- Environmental and Otherwise.md
This commit is contained in:
commit
ee53bfbc39
@ -1,222 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (HankChow)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: subject: (Bash Variables: Environmental and Otherwise)
|
||||
[#]: via: (https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-otherwise)
|
||||
[#]: author: (Paul Brown https://www.linux.com/users/bro66)
|
||||
[#]: url: ( )
|
||||
|
||||
Bash Variables: Environmental and Otherwise
|
||||
======
|
||||

|
||||
|
||||
Bash variables, including those pesky _environment variables_ , have been popped up several times in previous articles, and it’s high time you get to know them better and how they can help you.
|
||||
|
||||
So, open your terminal window and let's get started.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Consider `HOME`. Apart from the cozy place where you lay down your hat, in Linux it is a variable that contains the path to the current user's home directory. Try this:
|
||||
|
||||
```
|
||||
echo $HOME
|
||||
```
|
||||
|
||||
This will show the path to your home directory, usually _/home/_.
|
||||
|
||||
As the name indicates, variables can change according to the context. Indeed, each user on a Linux system will have a `HOME` variable containing a different value. You can also change the value of a variable by hand:
|
||||
|
||||
```
|
||||
HOME=/home/<your username>/Documents
|
||||
```
|
||||
|
||||
will make `HOME` point to your _Documents/_ folder.
|
||||
|
||||
There are three things to notice here:
|
||||
|
||||
1. There are no spaces between the name of the variable and the `=` or between the `=` and the value you are putting into the variable. Spaces have their own meaning in the shell and cannot be used any old way you want.
|
||||
2. If you want to put a value into a variable or manipulate it in any way, you just have to write the name of the variable. If you want to see or use the contents of a variable, you put a `$` in front of it.
|
||||
3. Changing `HOME` is risky! A lot programs rely on `HOME` to do stuff and changing it can have unforeseeable consequences. For example, just for laughs, change `HOME` as shown above and try typing `cd` and then [Enter]. As we have seen elsewhere in this series, you use `cd` to _c_ hange to another _d_ irectory. Without any parameters, `cd` takes you to your home directory. If you change the `HOME` variable, `cd` will take you to the new directory `HOME` points to.
|
||||
|
||||
|
||||
|
||||
Changes to environment variables like the one described in point 3 above are not permanent. If you close your terminal and open it back up, or even open a new tab in your terminal window and move there, `echo $HOME` will show its original value.
|
||||
|
||||
Before we go on to how you make changes permanent, let's look at another environment variable that it does make sense changing.
|
||||
|
||||
### PATH
|
||||
|
||||
The `PATH` variable lists directories that contain executable programs. If you ever wondered where your applications go when they are installed and how come the shell seems to magically know which programs it can run without you having to tell it where to look for them, `PATH` is the reason.
|
||||
|
||||
Have a look inside `PATH` and you will see something like this:
|
||||
|
||||
```
|
||||
$ echo $PATH
|
||||
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
|
||||
```
|
||||
|
||||
Each directory is separated by a colon (`:`) and if you want to run an application installed in any directory other than the ones listed in `PATH`, you will have to tell the shell where to find it:
|
||||
|
||||
```
|
||||
/home/<user name>/bin/my_program.sh
|
||||
```
|
||||
|
||||
This will run a program calle _my_program.sh_ you have copied into a _bin/_ directory in your home directory.
|
||||
|
||||
This is a common problem: you don't want to clutter up your system's _bin/_ directories, or you don't want other users running your own personal scripts, but you don't want to have to type out the complete path every time you need to run a script you use often. The solution is to create your own _bin/_ directory in your home directory:
|
||||
|
||||
```
|
||||
mkdir $HOME/bin
|
||||
```
|
||||
|
||||
And then tell `PATH` all about it:
|
||||
|
||||
```
|
||||
PATH=$PATH:$HOME/bin
|
||||
```
|
||||
|
||||
After that, your _/home//bin_ will show up in your `PATH` variable. But... Wait! We said that the changes you make in a given shell will not last and will lose effect when that shell is closed.
|
||||
|
||||
To make changes permanent for your user, instead of running them directly in the shell, put them into a file that gets run every time a shell is started. That file already exists and lives in your home directory. It is called _.bashrc_ and the dot in front of the name makes it a hidden file -- a regular `ls` won't show it, but `ls -a` will.
|
||||
|
||||
You can open it with a text editor like [kate][1], [gedit][2], [nano][3], or [vim][4] (NOT LibreOffice Writer -- that's a word processor. Different beast entirely). You will see that _.bashrc_ is full of shell commands the purpose of which are to set up the environment for your user.
|
||||
|
||||
Scroll to the bottom and add the following on a new, empty line:
|
||||
|
||||
```
|
||||
export PATH=$PATH:$HOME/bin
|
||||
```
|
||||
|
||||
Save and close the file. You'll be seeing what `export` does presently. In the meantime, to make sure the changes take effect immediately, you need to `source` _.bashrc_ :
|
||||
|
||||
```
|
||||
source .bashrc
|
||||
```
|
||||
|
||||
What `source` does is execute _.bashrc_ for the current open shell, and all the ones that come after it. The alternative would be to log out and log back in again for the changes to take effect, and who has the time for that?
|
||||
|
||||
From now on, your shell will find every program you dump in _/home//bin_ without you having to specify the whole path to the file.
|
||||
|
||||
### DYI Variables
|
||||
|
||||
You can, of course, make your own variables. All the ones we have seen have been written with ALL CAPS, but [you can call a variable more or less whatever you want][5].
|
||||
|
||||
Creating a new variables is straightforward: just set a value within it:
|
||||
|
||||
```
|
||||
new_variable="Hello"
|
||||
```
|
||||
|
||||
And you already know how to recover a value contained within a variable:
|
||||
|
||||
```
|
||||
echo $new_variable
|
||||
```
|
||||
|
||||
You often have a program that will require you set up a variable for things to work properly. The variable may set an option to "on", or help the program find a library it needs, and so on. When you run a program in Bash, the shell spawns a daughter process. This means it is not exactly the same shell that executes your program, but a related mini-shell that inherits some of the mother's characteristics. Unfortunately, variables, by default, are not one of them. This is because, by default again, variables are _local_. This means that, for security reasons, a variable set in one shell cannot be read in another, even if it is a daughter shell.
|
||||
|
||||
To see what I mean, set a variable:
|
||||
|
||||
```
|
||||
robots="R2D2 & C3PO"
|
||||
```
|
||||
|
||||
... and run:
|
||||
|
||||
```
|
||||
bash
|
||||
```
|
||||
|
||||
You just ran a Bash shell program within a Bash shell program.
|
||||
|
||||
Now see if you can read the contents of you variable with:
|
||||
|
||||
```
|
||||
echo $robots
|
||||
```
|
||||
|
||||
You should draw a blank.
|
||||
|
||||
Still inside your bash-within-bash shell, set `robots` to something different:
|
||||
|
||||
```
|
||||
robots="These aren't the ones you are looking for"
|
||||
```
|
||||
|
||||
Check `robots`' value:
|
||||
|
||||
```
|
||||
$ echo $robots
|
||||
These aren't the ones you are looking for
|
||||
```
|
||||
|
||||
Exit the bash-within-bash shell:
|
||||
|
||||
```
|
||||
exit
|
||||
```
|
||||
|
||||
And re-check the value of `robots`:
|
||||
|
||||
```
|
||||
$ echo $robots
|
||||
R2D2 & C3P0
|
||||
```
|
||||
|
||||
This is very useful to avoid all sorts of messed up configurations, but this presents a problem also: if a program requires you set up a variable, but the program can't access it because Bash will execute it in a daughter process, what can you do? That is exactly what `export` is for.
|
||||
|
||||
Try doing the prior experiment, but, instead of just starting off by setting `robots="R2D2 & C3PO"`, export it at the same time:
|
||||
|
||||
```
|
||||
export robots="R2D2 & C3PO"
|
||||
```
|
||||
|
||||
You'll notice that, when you enter the bash-within-bash shell, `robots` still retains the same value it had at the outset.
|
||||
|
||||
**Interesting fact:** While the daughter process will "inherit" the value of an exported variable, if the variable is changed within the daughter process, changes will not flow upwards to the mother process. In other words, changing the value of an exported variable in a daughter process does not change the value of the original variable in the mother process.
|
||||
|
||||
You can see all exported variables by running
|
||||
|
||||
```
|
||||
export -p
|
||||
```
|
||||
|
||||
The variables you create should be at the end of the list. You will also notice some other interesting variables in the list: `USER`, for example, contains the current user's user name; `PWD` points to the current directory; and `OLDPWD` contains the path to the last directory you visited and since left. That's because, if you run:
|
||||
|
||||
```
|
||||
cd -
|
||||
```
|
||||
|
||||
You will go back to the last directory you visited and `cd` gets the information from `OLDPWD`.
|
||||
|
||||
You can also see all the environment variables using the `env` command.
|
||||
|
||||
To un-export a variable, use the `-n` option:
|
||||
|
||||
```
|
||||
export -n robots
|
||||
```
|
||||
|
||||
### Next Time
|
||||
|
||||
You have now reached a level in which you are dangerous to yourself and others. It is time you learned how to protect yourself from yourself by making your environment safer and friendlier through the use of _aliases,_ and that is exactly what we'll be tackling in the next episode. See you then.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-otherwise
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.kde.org/applications/utilities/kate/
|
||||
[2]: https://help.gnome.org/users/gedit/stable/
|
||||
[3]: https://www.nano-editor.org/
|
||||
[4]: https://www.vim.org/
|
||||
[5]: https://bash.cyberciti.biz/guide/Rules_for_Naming_variable_name
|
@ -0,0 +1,212 @@
|
||||
Bash 环境变量的那些事
|
||||
======
|
||||

|
||||
|
||||
bash 变量,尤其是讨厌的环境变量,已经是一个老生常谈的话题了。我们也更应该对它有一个详细的了解,让它为我们所用。
|
||||
|
||||
下面就打开终端,开始吧。
|
||||
|
||||
### 环境变量
|
||||
|
||||
`HOME` 除了是你脱下帽子惬意休息的地方,同时也是 Linux 中的一个变量,它是当前用户主目录的路径:
|
||||
|
||||
```
|
||||
echo $HOME
|
||||
```
|
||||
|
||||
以上这个命令会显示当前用户的主目录路径,通常都在 `/home/` 下。
|
||||
|
||||
顾名思义,一个变量的值并不是固定的。实际上,Linux 系统中每一个用户的 `HOME` 变量都是不一样的,当然你也可以这样自行更改 `HOME` 变量的值:
|
||||
|
||||
```
|
||||
HOME=/home/<your username>/Documents
|
||||
```
|
||||
|
||||
以上这个命令将会把 `HOME` 变量设置为 `/home/<your username>/Documents` 目录。
|
||||
|
||||
其中有三点需要留意:
|
||||
|
||||
1. `=` 符号和其两侧的内容之间不加空格。空格在 shell 中有专门的意义,不能随意地在任何地方添加空格。
|
||||
2. 如果你需要对变量进行赋值,只需要使用变量名称就可以了。但如果需要读取或者使用变量的值,需要在变量前面加上一个 `$` 号。
|
||||
3. 更改 `HOME` 变量具有一定的风险。有很多程序是依赖于 `HOME` 变量的,更改 `HOME` 变量可能会导致一些不可预见的结果。例如,如果按照上面的方式更改了 `HOME` 变量,然后执行不带有任何参数的 `cd` 命令,在通常情况下,会跳转到用户的主目录下,但在这个时候,会跳转到 `HOME` 变量指定的目录下。
|
||||
|
||||
上面第 3 点中环境变量的更改并不是持久有效的,在终端关闭后重新打开终端,又或者是新建一个终端,执行 `echo $HOME` 命令输出的仍然会是初始的值,而不是重新自定义的值。
|
||||
|
||||
在讨论如何持久地更改一个环境变量之前,我们先来看一下另一个比较重要的环境变量。
|
||||
|
||||
### PATH 变量
|
||||
|
||||
在 `PATH` 变量中存放了一系列目录,而且是放置了可执行程序的目录。正是由于 `PATH` 变量的存在,让你不需要知道应用程序具体安装到了什么目录,而 shell 却可以正确地找到这些应用程序。
|
||||
|
||||
如果你查看 `PATH` 变量的值,大概会是以下这样:
|
||||
|
||||
```
|
||||
$ echo $PATH
|
||||
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
|
||||
```
|
||||
|
||||
每两个目录之间使用冒号(`:`)分隔。如果某个应用程序的所在目录不在 `PATH` 变量中,那么运行的时候就需要声明应用程序的目录让 shell 能够找到。
|
||||
|
||||
```
|
||||
/home/<user name>/bin/my_program.sh
|
||||
```
|
||||
|
||||
例如以上命令就会执行当前用户 `bin/` 目录下的 `my_program.sh` 文件。
|
||||
|
||||
有一个常见的问题:如果你不希望弄乱系统的 `bin/` 目录,同时也不希望你自己的文件被其它人运行,还不想每次运行的时候都要输入完整的路径,那么,你可以在你的主目录中创建一个独立的 `bin/` 目录:
|
||||
|
||||
```
|
||||
mkdir $HOME/bin
|
||||
```
|
||||
|
||||
然后将这个目录添加到 `PATH` 变量中:
|
||||
|
||||
```
|
||||
PATH=$PATH:$HOME/bin
|
||||
```
|
||||
|
||||
然后 `/home/<user name>/bin/` 目录就会出现在 `PATH` 变量中了。但正如之前所说,这个变更只会在当前的 shell 生效,当前的 shell 一旦关闭,环境变量的值就又恢复原状了。
|
||||
|
||||
如果要让变更对当前用户持续生效,就不能在 shell 中直接执行对应的变更,而是应该将这些变更操作卸载每次启动 shell 时都会运行的文件当中。这个文件就是当前用户主目录中的 `.bashrc` 文件。文件名前面的点号表明这是一个隐藏文件,执行普通的 `ls` 命令是不会将这个文件显示出来的,但只要在 `ls` 命令中加入 `-a` 参数就可以看到这个文件了。
|
||||
|
||||
你可以使用诸如 [kate][1]、[gedit][2]、[nano][3] 或者 [vim][4] 这些文本编辑器来打开 `.bashrc` 文件(但不要用 LibreOffice Writer,它是一个文字处理软件,跟前面几个文字编辑器并不一个量级的东西)。打开 `.bashrc` 文件之后,你会看见里面放置了一些 shell 命令,是用于为当前用户设置环境的。
|
||||
|
||||
在文件的末尾添加新行并输入以下内容:
|
||||
|
||||
```
|
||||
export PATH=$PATH:$HOME/bin
|
||||
```
|
||||
|
||||
保存并关闭 `.bashrc` 文件,接下来你就会看到 `export` 语句的效果。执行以下的命令让刚才的修改立即生效:
|
||||
|
||||
```
|
||||
source .bashrc
|
||||
```
|
||||
|
||||
刚才执行的 `source` 命令让 `.bashrc` 文件在当前的 shell 立即生效,并且对于之后打开的 shell 都会有效。因此另一个等效的方法是退出并重新进入 shell,但这样也太麻烦了。
|
||||
|
||||
现在,你的 shell 就能自动寻找到 `/home/<user name>/bin/` 下的程序了,执行这个目录下的程序也不需要完整地写出程序的路径。
|
||||
|
||||
### 自定义变量
|
||||
|
||||
当然,你也可以定义自己的变量。刚才我们看到的变量名称都是全大写的,实际上[变量名称的定义还是比较灵活的][5]。
|
||||
|
||||
定义新变量的过程非常直观,直接对它赋值就可以了:
|
||||
|
||||
```
|
||||
new_variable="Hello"
|
||||
```
|
||||
|
||||
然后可以用一下的方式读取到已定义变量的值:
|
||||
|
||||
```
|
||||
echo $new_variable
|
||||
```
|
||||
|
||||
程序的正常工作离不开各种变量,例如要将某个选项设置为 on,又或者让程序找到所需的代码库,都需要使用变量。在 bash 中运行程序的时候会生成一个子 shell,这个子 shell 和执行原程序的父 shell 并不是完全一样的,只是继承了父 shell 的部分内容,而且默认是不继承父 shell 中的变量的。因为变量默认情况下是局部变量,出于安全原因,一个 shell 中的局部变量不会被另一个 shell 读取到,即使是子 shell 也不可以。
|
||||
|
||||
下面举一个例子。首先定义一个变量:
|
||||
|
||||
```
|
||||
robots="R2D2 & C3PO"
|
||||
```
|
||||
|
||||
然后执行:
|
||||
|
||||
```
|
||||
bash
|
||||
```
|
||||
|
||||
现在是在 bash shell 中创建了一个子 shell。
|
||||
|
||||
执行这个命令看看还能不能读取到刚才定义的变量:
|
||||
|
||||
```
|
||||
echo $robots
|
||||
```
|
||||
|
||||
你会发现读取不到。
|
||||
|
||||
还是在这个子 shell 中,为 `robots` 变量赋一个不同的值:
|
||||
|
||||
```
|
||||
robots="These aren't the ones you are looking for"
|
||||
```
|
||||
|
||||
再读取一次:
|
||||
|
||||
```
|
||||
$ echo $robots
|
||||
These aren't the ones you are looking for
|
||||
```
|
||||
|
||||
退出这个子 shell:
|
||||
|
||||
```
|
||||
exit
|
||||
```
|
||||
|
||||
然后再看一下现在 `robots` 变量的值:
|
||||
|
||||
```
|
||||
$ echo $robots
|
||||
R2D2 & C3P0
|
||||
```
|
||||
|
||||
这一个特性可以有效避免配置过程中产生混乱,同时也会导致一个问题:如果程序中需要设置变量,但却由于子 shell 的原因无法正常访问到这个变量,该如何解决呢?这个时候就需要用到 `export` 了。
|
||||
|
||||
重复一次刚才的过程,但这一次不是通过 `robots="R2D2 & C3PO"` 方式来设置变量,而是使用 `export` 命令:
|
||||
|
||||
```
|
||||
export robots="R2D2 & C3PO"
|
||||
```
|
||||
|
||||
现在你会发现,在进入子 shell 之后,`robots` 变量的值仍然是最初赋予的值。
|
||||
|
||||
要注意的是,尽管子 shell 会继承通过 `export` 导出的变量,但如果在子 shell 中对这个变量重新赋值,是不会影响到父 shell 中对应变量的。
|
||||
|
||||
如果要查看所有通过 `export` 导出的变量,可以执行以下命令:
|
||||
|
||||
```
|
||||
export -p
|
||||
```
|
||||
|
||||
自定义的变量会显示在这个列表的末尾。这个列表中还有一些常见的变量:例如 `USER` 的值是当前用户的用户名,`PWD` 的值是当前用户当前所在的目录,而 `OLDPWD` 的值则是当前用户上一个访问过的目录。因此如果执行:
|
||||
|
||||
```
|
||||
cd -
|
||||
```
|
||||
|
||||
就会切换到上一个访问过的目录,那是因为 `cd` 命令读取到了 `OLDPWD` 变量的值。
|
||||
|
||||
你也可以使用 `env` 命令查看所有环境变量。
|
||||
|
||||
如果要取消导出一个变量,可以加上 `-n` 参数:
|
||||
|
||||
```
|
||||
export -n robots
|
||||
```
|
||||
|
||||
### 接下来
|
||||
|
||||
了解过环境变量的知识之后,你已经到达了可能对自己和他人造成危险的水平,接下来就需要了解如何通过使用 `_aliases` 来让环境变得更安全、更友好以保护自己了。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-otherwise
|
||||
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.linux.com/users/bro66
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.kde.org/applications/utilities/kate/
|
||||
[2]: https://help.gnome.org/users/gedit/stable/
|
||||
[3]: https://www.nano-editor.org/
|
||||
[4]: https://www.vim.org/
|
||||
[5]: https://bash.cyberciti.biz/guide/Rules_for_Naming_variable_name
|
||||
|
Loading…
Reference in New Issue
Block a user