0%

Shell 非标准特性

使用正确的 shell

事实证明,所有主要的交互式 shell 都允许指定应该使用哪个 shell(实际上是 Unix 或 Linux 发行版中包含的数千个程序)来运行该文件。如果文件第一行的前两个字符是 #!,则该行的其余部分指定该文件的解释器。因此 #!/bin/ksh 指定 Korn shell#!/bin/bash 指定 Bash

如果使用特定于某个 shell 的构造或符号约定,则可以使用此功能强制该 shell 运行你的程序,从而避免兼容性问题。由于可以指定所需的任何程序,因此以 #!/usr/bin/perl 开头的 Perl 程序会强制 shell 调用 /usr/bin/perl 来解释文件中的行。然而,必须谨慎使用此功能,因为许多程序(例如 Perl)并不驻留在每个 Unix 系统上的标准位置。此外,POSIX 标准并未指定这一点,尽管它存在于每个现代 shell 中,甚至在许多 Unix 版本的操作系统级别上实现。

最常见的是,会看到系统 shell 程序使用此表示法来确保使用 Bourne Shell,无论用户的登录 shell 是什么,都以 #!/bin/sh 开头。

ENV file

当启动 shell 时,它所做的第一件事就是在环境中查找名为 ENV 的变量。如果找到它并且它不为空,则将执行 ENV 指定的文件,就像登录时执行 .profile 一样。ENV 文件包含用于设置 shell 环境的命令。

如果要使用 ENV file,应该在 .profile 中设置并 export 这个变量,export ENV=$HOME/.alias

Command line Editing

set -o vi,可以在命令行中使用 vi 的指令。ESC 进入 vi 模式,$到行尾,0 到行首,w b 2w 在单词间快速移动。

alias

别名是 shell 提供的速记符号,用于允许自定义命令。 shell 保留一个别名列表,在任何其他替换发生之前输入命令时将搜索该列表。如果命令行的第一个单词是别名,则它将被别名的文本替换。

alias name='string'alias ll='ls -l'

echo ${PWD##*/} 获取当前目录名称,##*/ 这是一种参数扩展语法,这部分是一个参数扩展(Parameter Expansion)的用法,其中 ##*/ 是模式匹配操作符。#:从字符串的开头删除匹配的模式(最短匹配)。##:从字符串的开头删除匹配的模式(最长匹配)。*/:匹配路径中的任意字符直到最后一个斜杠 /

定义别名时要注意引号的使用。

alias dir="echo ${PWD##*/}",其实就相当于 alias dir="echo somedir",在切换目录后,别名不起左右,这里应该使用单引号。

如果在定义别名时,值后包含一个引号,shell 会检查别名后的内容,尝试进行 别名替换。

alias nohup="/bin/nohup "nohup ll,shell 会尝试别名替换 ll

Quoting a command or prefacing it with a backslash prevents alias substitution。

removing aliases

unalias nameunalias –a 移除所以别名。

Array

Job Control

1
2
3
4
5
6
7
$ sleep 100 &
$ sleep 200 &
$ sleep 300 &
$ jobs -l
[1] Running sleep 100 &
[2]- Running sleep 200 &
[3]+ Running sleep 300 &

最近放到后台执行的后面有个 +,其次是 -,某些内置命令可以利用这些符号。

比如 kill,the argument to it can be a process ID or a percent sign (%) followed by a job number, a + (current job), a – (previous job), or another % (also current job)

Stopped Jobs and the fg and bg Commands

如果一个任务在前台运行可以使用 ctrl+z,停止这个任务,并且会成为当前作业,即有个 + 号。

要让它继续执行的话可以使用 fgbg

  1. fg: The fg command causes the current job to resume execution in the foreground
  2. bg: The bg causes the current job to resume execution in the background

都是针对 current job 即有 + 的进程。也可以通过 job number、命令的前几个字符、+、-、% 等来使用。

后台运行的程序输出默认到终端,有时会干扰工作,可以设置 stty tostop,当后台程序要输出东西时立马停止,并打印一些内容到终端,此时可以使用 fg 查看输出内容。

  1. The shell first checks to see whether the command is a reserved word (such as for or do).
  2. If it’s not a reserved word and is not quoted, the shell next checks its alias list, and if it finds a match, performs the substitution. If the alias definition ends in a space, it also attempts alias substitution on the next word. The final result is then checked against the reserved word list, and if it’s not a reserved word, the shell proceeds to step 3.
  3. The shell checks the command against its function list and executes the eponymous function if found.
  4. The shell checks to see whether the command is a built-in command (such as cd and pwd).
  5. Finally, the shell searches the PATH to locate the command.
  6. If the command still isn’t found, a “command not found” error message is issued.