shell记录位置

登入取得的 shell 就记录在/etc/passwd

命令记录:

~/.bash_history 记录的是前一次登入以前所执行过的指令, 而至于这一次登入所执行的指令都被暂存在内存中,当你成功的注销系统后,该指令记忆才会记录到 .bash_history。

tab功能提示键在bash当中才有!

命令别名设定功能: (alias)

1
2
为ls -al设置别名
alias lm='ls -al'

Bash shell 的功能

  1. 命令编修能力 (history)
  2. 命令与文件补全功能
  3. 命令别名设定功能: (alias)
  4. 工作控制、前景背景控制
  5. 程序化脚本: (shell scripts)
  6. 通配符: (Wildcard)

查询指令是否为 Bash shell 的内建命令: type

1
2
3
4
5
6
7
8
9
$ type [-tpa] name
选项与参数:
:不加任何选项与参数时,type 会显示出 name 是外部指令还是 bash 内建指令
-t:当加入 -t 参数时,type 会将 name 以底下这些字眼显示出他的意义:
file :表示为外部指令;
alias :表示该指令为命令别名所设定的名称;
builtin :表示该指令为 bash 内建的指令功能;
-p :如果后面接的 name 为外部指令时,才会显示完整文件名;
-a :会由 PATH 变量定义的路径中,将所有含 name 的指令都列出来,包含 alias
1
2
3
4
5
6
7
8
9
$ type ls
ls is aliased to `ls --color=auto' <==未加任何参数,列出 ls 的最主要使用情况
$ type -t ls
alias <==仅列出 ls 执行时的依据
$ type -a ls
ls is aliased to `ls --color=auto' <==最先使用 aliase
ls is /usr/bin/ls <==还有找到外部指令在 /bin/ls
$ type cd
cd is a shell builtin <==cd 是 shell 内建指令

每个账号的邮件信箱预设是以 MAIL 这个变量来进行存取,当xx登录时便会取得 MAIL 这个变量这个变量的内容其实就是 /var/spool/mail/xx

env

env 是 environment (环境) 的简写,列出来所有的环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SHELL=/bin/bash
VTE_VERSION=5200
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
XDG_CURRENT_DESKTOP=GNOME
GPG_AGENT_INFO=/run/user/0/gnupg/S.gpg-agent:0:1
GNOME_TERMINAL_SERVICE=:1.77
XDG_SEAT=seat0
SHLVL=1
GDMSESSION=gnome
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
LOGNAME=root
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
XDG_RUNTIME_DIR=/run/user/0
XAUTHORITY=/run/user/0/gdm/Xauthority
PATH=/usr/local/java/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/maven3/maven/bin
SESSION_MANAGER=local/elliot:@/tmp/.ICE-unix/1033,unix/elliot:/tmp/.ICE-unix/1033
GTK_IM_MODULE=fcitx

变量

HOME
代表用户的家目录。

SHELL
告知我们,目前这个环境使用的 SHELL 是哪支程序

HISTSIZE
这个与『历史命令』有关,亦即是, 我们曾经下达过的指令可以被系统记录下来,而记录的『笔数』则是由这个值来设定的。

MAIL
当我们使用 mail 这个指令在收信时,系统会去读取的邮件信箱文件 (mailbox)。

PATH
就是执行文件搜寻的路径啦~目录与目录中间以冒号(:)分隔, 由于文件的搜寻是依序由 PATH 的变量内的目录来查询。

LANG

语系数据

RANDOM
这个玩意儿就是『随机随机数』的变量啦!目前大多数的 distributions 都会有随机数生成器,那就是/dev/random 这个文件。 我们可以透过这个随机数文件相关的变量 ($RANDOM) 来随机取得随机数值

1
2
3
4
~# echo $RANDOM
17402
~# echo $RANDOM
23626

set 观察所有变量 (含环境变量与自定义变量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="8")
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="4" [2]="23" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
BASH_VERSION='4.4.23(1)-release'
CLASSPATH=.:/usr/local/java/jdk/lib
CLUTTER_IM_MODULE=xim
COLORTERM=truecolor
COLUMNS=80
......省略

PS1:(提示字符的设定)

1
[dmtsai@study ~]$(指的是这个)

上面的信息可以使用PS1(数字1)来设定,具体参数如下:

  • \d :可显示出『星期 月 日』的日期格式,如:”Mon Feb 2”
  • \H :完整的主机名。举例来说,鸟哥的练习机为『study.centos.vbird』
  • \h :仅取主机名在第一个小数点之前的名字,如鸟哥主机则为『study』后面省略
  • \t :显示时间,为 24 小时格式的『HH:MM:SS』
  • \T :显示时间,为 12 小时格式的『HH:MM:SS』
  • \A :显示时间,为 24 小时格式的『HH:MM』
  • \@ :显示时间,为 12 小时格式的『am/pm』样式
  • \u :目前使用者的账号名称,如『dmtsai』;
  • \v :BASH 的版本信息,如鸟哥的测试主机版本为 4.2.46(1)-release,仅取『4.2』显示
  • \w :完整的工作目录名称,由根目录写起的目录名称。但家目录会以 ~ 取代;
  • \W :利用 basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
  • \# :下达的第几个指令。
  • \$ :提示字符,如果是 root 时,提示字符为 # ,否则就是 $
1
2
3
[dmtsai@study ~]$ cd /home
[dmtsai@study home]$ PS1='[\u@\h \w \A #\#]\$ '
[dmtsai@study /home 17:02 #85]$ //具体参数含义见上
$:(关于本 shell 的 PID)
1
2
3
~# echo $$ //输出本shell的pid
1739
本shell的pid
?:(关于上个执行指令的回传值)

上一个执行的指令所回传的值,当我们执行某些指令时, 这些指令都会回传一个执行后的代码。一般来说,如果成功的执行该指令,则会回传一个 0 值,错误就会返回非0值。

1
2
3
4
~# echo $SHELL
/bin/bash
~# echo $?
0
OSTYPE, HOSTTYPE, MACHTYPE:(主机硬件与核心的等级)
1
2
3
4
5
6
~# echo $OSTYPE
linux-gnu
~# echo $HOSTTYPE
x86_64
~# echo $MACHTYPE
x86_64-pc-linux-gnu

export: 自定义变量转成环境变量

1
$ export 变量名称  //分享自己的变量设定给后来呼叫的文件或其他程序

影响显示结果的语系变量

1
locale -a //显示所有支持的变量

基本上,你可以逐一设定每个与语系有关的变量数据,但事实上,如果其他的语系变量都未设定, 且你有设定 LANG 或者是 LC_ALL 时,则其他的语系变量就会被这两个变量所取代

语系文件都放置在: /usr/lib/locale/ 这个目录中

变量的有效范围

环境变量=全局变量
自定义变数=局部变量

为什么环境变量可以被子程序所引用?

  • 当启动一个 shell,操作系统会分配一记忆区块给 shell 使用,此内存内之变量可让子程序取用
  • 若在父程序利用 export 功能,可以让自定义变量的内容写到上述的记忆区块当中(环境变量);
  • 当加载另一个 shell 时 (亦即启动子程序,而离开原本的父程序了),子 shell 可以将父 shell 的环境变量所在的记忆区块导入自己的环境变量区块当中。
变量键盘读取、数组与宣告: read, array, declare

read:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ read [-pt] variable
选项与参数:
-p :后面可以接提示字符!
-t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!

范例一:让用户由键盘输入一内容,将该内容变成名为 atest 的变量
[dmtsai@study ~]$ read atest
This is a test <==此时光标会等待你输入!请输入左侧文字看看
[dmtsai@study ~]$ echo ${atest}
This is a test <==你刚刚输入的数据已经变成一个变量内容!
范例二:提示使用者 30 秒内输入自己的大名,将该输入字符串作为名为 named 的变量内容
[dmtsai@study ~]$ read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai <==注意看,会有提示字符喔!
[dmtsai@study ~]$ echo ${named}
VBird Tsai <==输入的数据又变成一个变量的内容了!

declare / typeset:

1
2
3
4
5
6
7
8
9
10
11
12
13
declare [-aixr] variable
选项与参数:
-a :将后面名为 variable 的变量定义成为数组 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量设定成为 readonly 类型,该变量不可被更改内容,也不能 unset
范例一:让变量 sum 进行 100+300+50 的加总结果
[dmtsai@study ~]$ sum=100+300+50
[dmtsai@study ~]$ echo ${sum}
100+300+50 <==咦!怎么没有帮我计算加总?因为这是文字型态的变量属性啊!
[dmtsai@study ~]$ declare -i sum=100+300+50
[dmtsai@study ~]$ echo ${sum}
450

在默认的情况底下, bash 对于变量有几个基本的定义:
变量类型默认为『字符串』,所以若不指定变量类型,则 1+2 为一个『字符串』而不是『计算式』。 所以上述第一个执行的结果才会出现那个情况的;
bash 环境中的数值运算,预设最多仅能到达整数形态,所以 1/3 结果是 0;

1
2
3
4
5
6
7
8
9
10
11
12
范例二:将 sum 变成环境变量
[dmtsai@study ~]$ declare -x sum
[dmtsai@study ~]$ export | grep sum
declare -ix sum="450" <==果然出现了!包括有 i 与 x 的宣告!
范例三:让 sum 变成只读属性,不可更动!
[dmtsai@study ~]$ declare -r sum
[dmtsai@study ~]$ sum=tesgting
-bash: sum: readonly variable <==不能改这个变数了!
范例四:让 sum 变成非环境变量的自定义变量吧!
[dmtsai@study ~]$ declare +x sum <== 将 - 变成 + 可以进行『取消』动作
[dmtsai@study ~]$ declare -p sum <== -p 可以单独列出变量的类型
declare -ir sum="450" <== 看吧!只剩下 i, r 的类型,不具有 x 啰
变量的搜索路径:

查看搜索路径可以使用type -a命令

先 alias 再 builtin 再由 $PATH 找到 /bin/echo

bash 的进站与欢迎讯息: /etc/issue, /etc/motd

1
2
3
~# cat /etc/issue
Kali GNU/Linux Rolling \n \l
//可以 man issue 配合 man agetty 查看具体含义

telnet远程登录信息会记录在/etc/issue.net

如果您想要让使用者登入后取得一些讯息,例如您想要让大家都知道的讯息, 那么可以将讯息加入 /etc/motd 里面去。应该类似于系统公告。

bash 的环境配置文件

login 与 non-login shell
  • login shell:取得 bash 时需要完整的登入流程的,就称为 login shell。举例来说,你要由 tty1 ~ tty6 登入,需要输入用户的账号与密码,此时取得的 bash 就称为『 login shell 』
  • non-login shell:取得 bash 接口的方法不需要重复登入的举动,举例来说, (1)你以 X window 登入 Linux 后,再以 X 的图形化接口启动终端机,此时那个终端接口并没有需要再次的输入账号与密码,那个 bash 的环境就称为 non-login shell 了。(2)你在原本的 bash 环境下再次下达 bash 这个指令,同样的也没有输入账号密码, 那第二个 bash (子程序) 也是 non-login shell

login shell 其实只会读取这两个配置文件:

  • /etc/profile:这是系统整体的设定,你最好不要修改这个文件;
  • ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人设定,你要改自己的数据,就写入这里
/etc/profile (login shell 才会读):

每个使用者登入取得 bash 时一定会读取的配置文件

这个文件设定的变量主要有:

  • PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统指令目录;
  • MAIL:依据账号设定好使用者的 mailbox 到 /var/spool/mail/账号名;
  • USER:根据用户的账号设定此一变量内容;
  • HOSTNAME:依据主机的 hostname 指令决定此一变量内容;
  • HISTSIZE:历史命令记录笔数。CentOS 7.x 设定为 1000 ;
  • umask:包括 root 默认为 022 而一般用户为 002 等!

/etc/profile.d/*.sh
其实这是个目录内的众多文件!只要在 /etc/profile.d/ 这个目录内且扩展名为 .sh ,另外,使用者能够具有 r 的权限, 那么该文件就会被 /etc/profile 呼叫进来。在 CentOS 7.x 中,这个目录底下的文件规范了 bash 操作接口的颜色、 语系、ll 与 ls 指令的命令别名、vi 的命令别名、which的命令别名等等。如果你需要帮所有使用者设定一些共享的命令别名时, 可以在这个目录底下自行建立扩展名为 .sh 的文件,并将所需要的数据写入即可喔!

/etc/locale.conf
这个文件是由 /etc/profile.d/lang.sh 呼叫进来的!这也是我们决定 bash 预设使用何种语系的重要配置文件! 文件里最重要的就是 LANG/LC_ALL 这些个变量的设定啦!我们在前面的 locale 讨论过这个文件。

~/.bash_profile (login shell 才会读)

bash 在读完了整体环境设定的 /etc/profile 并藉此呼叫其他配置文件后,接下来则是会读取使用者的个人配置文件

所读取的个人偏好配置文件其实主要有三个,依序分别是:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

其实 bash 的 login shell 设定只会读取上面三个文件的其中一个, 而读取的顺序则是依照上面的顺序。也就是说,如果 ~/.bash_profile 存在,那么其他两个文件不论有无存在,都不会被读取。 如果~/.bash_profile 不存在才会去读取 ~/.bash_login。

使文件生效:(配置完环境变量之后可以使用source立即生效)

$ source 配置文件档名
范例:将家目录的 ~/.bashrc 的设定读入目前的 bash 环境中

~/.bashrc (non-login shell 会读)

万一你没有 ~/.bashrc (可能自己不小心将他删除了),那么可以复制 /etc/skel/.bashrc 到你的家目录,再修订一下你所想要的内容, 并使用 source 去呼叫 ~/.bashrc ,那你的命令提示字符就会回来啦.

/etc/man_db.conf

这的文件的内容『规范了使用 man 的时候, man page 的路径到哪里去寻找!』

~/.bash_history
还记得我们在历史命令提到过这个文件吧?预设的情况下, 我们的历史命令就记录在这里啊!而这个文件能够记录几笔数据,则与 HISTFILESIZE 这个变数有关.

~/.bash_logout
这个文件则记录了『当我注销 bash 后,系统再帮我做完什么动作后才离开』的意思。 你可以去读取一下这个文件的内容,预设的情况下,注销时, bash 只是帮我们清掉屏幕的讯息而已。 不过,你也可以将一些备份或者是其他你认为重要的工作写在这个文件中 (例如清空暂存盘), 那么当你离开 Linux 的时候,就可以解决一些烦人的事情.

$ stty [-a]

选项与参数:
-a
:将目前所有的 stty 参数列出来;