您的位置:首页 > 运维架构 > Shell

使用Bash编写Liunx 脚本程序——3、文件、用户和外壳的自定义设置

2016-04-12 15:49 537 查看
我的一个朋友刚买了了一台Unix计算机,控制台显示不是非常合适,例如我们查看一个文件时,操作系统不知道屏幕有多大,它显示了整个文件而不是每次一屏。
那时,我的计算机水平也不是很好,但是我记得有一个stty命令可以更改显示的属性,我查看了stty的帮助文档,注意到有两条设置命令rows和line,想当然的认为line应该是行数,于是我输入stty line 24。计算机停止响应,迫使我们重新启动了计算机。
我打电话给一位Unix专家,他有同样的操作系统。他说:“这条命令应该是正确的,让我试一试。”过了一会,他接着说:“我的计算机也挂了”。
结果这条命令是设置用来显示的串口号,把它设置为24,而串口24号没有接显示器,当然屏幕不会有任何显示。基于Unix的操作系统(如Linux)有大量的选项可以设置,有时是很难猜测出它们的实际作用的。本章是对上一章内容的扩充,涵盖了更多的基本命令和容易混淆的选项。
列出文件

命令ls的功能是显示出当前目录中的内容。虽然ls在所有的Unix型操作系统中都是有效的,Linux使用的ls命令来自于GNU fileutils项目而且还有许多得数的开关和特性。
$ls
archive check-orders.sh orders.txt
ls命令开关可以设置如何列出这些文件、显示的细度、排列的顺序和列数。大部分已发行的Linux设置为ls命令的某个缺省配置。例如Red Hat缺省有-q和-F设置。从写脚本的角度来说,使用ls命令而没有设置适当的开关是不安全的,因为你不能确定你的发行版本中是否包含了缺省值。
ls命令不显示以句号开始的文件。通常这些是Linux文件的配置文件、历史文件和其他用户不会使用的文件。如果要显示这些文件需要加上-A开关。使用-a将显示两个固有的文件.和..文件。
$ ls
.bash_history .bash_logout .bash_profile .bashrc archive check-orders.sh orders.txt
文件名可以根据它们的类型以不同的颜色进行显示。颜色的定义在/etc/DIR_COLORS文件中。你可以在自己的目录中使用.dir_colors文件定义自己的颜色。文件的格式和/etc/DIR_COLORS文件中的格式一样。
也可以使用符号而不是颜色进行文件类型的标示,使用—color和—classify(或-F)开关(在大部分Linux发行版中,这个特性使用别名来打开)。
$ ls --color=nerver --classify
archive/ check-orders.sh* orders.txt
-classify符号的描述是目录(/)、程序(*)、符号链接文件(@)、管道(|)、Unix域套接文件(=)。这些符号不是名字的组成部分:它们标示了文件的类型。本例中,archive是一个目录,check-orders.sh是一个程序。
另一个非常有用的开关是—hide-control-chars(或-q)。Linux文件名可以包含任何字符,甚至是控制字符。文件名包含因此字符也是可能的。如果有这种情况,更改文件名或删除文件名是不可以的,除非你知道隐含的文件名是什么。--hide-control-chars开关将控制是否显示文件名中不可以打印的文件名,不可显示的文件名以问号符号进行显示,可以标示出它们的位置。
$ rm orders.txt
rm:orders.txt non-existent
$ ls –color=never –classify –hide-control-chars
archive/ check-orders.sh* orde?rs.txt
本章的结尾将显示所有的开关。
printf命令

内置的printf命令用于在屏幕上显示一条消息,在外壳脚本程序中会经常使用这条命令。
printf命令类似于C语言中I/O函数printf(),但是它们是不同的。特定在单引号和双引号的使用上是完全不同的。
第一个参数是一串格式字符串,表示了如何显示这些字符串。例如:“%d”表示整数,“%f”表示浮点数。
$ printf “%d/n” 5
5
$ printf “%f/n” 5
5.000000
你要打印的每个值包含在格式代码中,格式代码将以合适的形式被变量值所替换掉。格式字符串中非指令格式的字符将会原样打印出来。
$ print “There are %d customers with purchases over %d./n” 50 20000
There are 50 customers with purchases over 20000.
printf命令有时可以将一个变量或不更改输入的值从新定向到命令。例如:将变量通过管道输入到命令中。不使用printf,Bash提供了一个快捷符号”<<<”,来重定向。“<<<”用来将一个字符串重定向到命令中,就像管道一样。
tr命令用来将文本从小写改为大写。本例显示了转换过程中的出错信息。
$ printf “%s/n” “$ERRMSG” | tr [:lower:] [:upper:]
WARNING: THE FILES FROM THE OHIO OFFICE HAVEN’T ARRIVERD.
$ tr[:lower:] [:upper:]
WARNING: THE FILES FROM THE OHIO OFFICE HAVEN’T ARRIVED.
格式代码如下列所示:
n %a——16进制的浮点数,使用小写字母
n %A——16进制的浮点数,使用大写字符
n %b——扩充反斜线符号序列
n %c——单个字符
n %e——显示浮点数,以指数形式显示
n %d——显示一个有符号数
n %f(或%F)——显示浮点数,不使用指数形式
n %g——根据显示的值来决定使用%e或%f
n %i——同%d
n %o——显示八进制数
n %q——引用一个字符串以便可以被外壳脚本程序正常读取
n %s——显示一个非引用字符串
n %u——显示一个无符号数
n %x——显示一个无符号的16进制数,使用小写字母
n %X——显示一个有符号16进制数,使用大写字母
n %%——显示一个百分号
如果一个数太长,Bash会报告超长的错误提示。
$ printf “%d/n” 123456789123456789012
bash: printf: warning: 123456789123456789012: Numerical result out of range
为了和C语言的printf兼容,Bash也识别下列标志,但是和%d的含义相同:
n %j——C语言的intmax_t或uintmax_t整数
n %t——C语言的ptrdiff_t整数
n %z——C语言的size_t或ssize_t整数
为了C的兼容性,你可以使用l或L来表示长整数。
%q格式在脚本程序中是非常重要的,在第五章“变量”中会详细讨论。
为了有报表的样式,可以指定要显示的信息的宽度。例如:“%10d”显示一个有符号数有10列的宽度。
$printf “%10d/n” 11
11
同样可以设定显示的列为左对齐。
$printf ”%-10d %-10d/n” 11 12
11 12
带有小数点的数表示要显示的数的长度和最小的精确度。例如:“%10.5f”表示一个浮点数的长度为10个字符,小数点的精度为5位。
$ printf “%10.5f/n” 17.2
17.20000
最后,撇号用来显示当前国家的千分位数。
“/n”格式字符串是一个用反斜杠开头的格式字符表示是不可显示的字符。“/n”表示换行。反斜杠开头的格式字符用来表示不可以显示的字符。
n /b——退格
n /f——换页
n /n——换行
n /r——回车
n /t——制表符
n /v——垂直制表符
n /`——单引号字符(兼容C)
n //——退格
n /0n——n是一个八进制数表示一个8bit的ASCII字符
$ printf “Two separate/nlines/n”
Two separate
lines
printf命令将0开头的数认作8进制数据,0x开头的数据认作16进制数据。他还能在不同进制的数据进行转换。
$ printf “%d/n” 010
8
$ printf “%d/n” 0xF
15
$ printf “0x%x/n” 15
0xF
$ printf “0%o/n” 8
010
大部分发行的Linux都有独立的printf命令用来和POSIX标准进行兼容。
获取帮助

Bash外壳命令有一个内置的help命令用来描述不同的内置Bash命令。“-s”开关用来显示你指定的命令的概述。
$help –s printf
printf: printf format [arguments]
help命令只显示Bash命令。为了获取Linux命令的帮助,你需要使用man(manual)命令。
$man date
Linux系统把手册页按照逻辑卷进行划分。man 显示所有卷中和命令相匹配的内容。卷1包含了外壳脚本可以执行的内容。为了限制帮助名字在外壳脚本中使用命令man 1。
$ man 1 date
如果你要找的内容在不止一卷手册中,只显示第一卷的内容,要想显示所有卷的内容,你需要使用“-a”的开关。
“-k”开关用来在Linux手册中查找特定的关键词并列出引用到这个关键词的手册页。
$ man 1 -k alias
help type命令给你和man 1 type命令不同的信息。help type命令告诉你关于Bash内置命令type的信息。而man 1 type会告诉你关于Linux命令type的信息。如果你不能确定该命令是否为Bash命令,可以在使用man命令之前试一下help命令。
修正显示

有时,Bash会话会变得不稳定。每个字符队列不能锁定你的显示,你打印出来的字符不能显示或显示为很奇怪的字符。例如:你尝试显示一个二进制字符,会发生这种情况。
命令reset会尝试恢复Bash会话到一个安全和正常的状态。
如果reset命令失败,你可以使用stty sane来恢复会话到一个正常的状态。
命令clear清除显示并恢复光标到屏幕的左上角。
对文件的操作

Linux有几个命令可以删除、拷贝和移动文件。
mkdir(make directory)建立一个新的目录。使用mkdir来管理你的文件。
$ mkdir prototypes
$ ls -l
total 4
drwxr –xr-x 2 ken users 4096 Jan 24 12:50 prototypes
mkdir命令有两个开关
n --mode=m(-m)——设置允许模式(就像使用chmod)
n --parents (-p)——即使这些目录不存在也建立所有必要的目录
$mkdir --parents --mode=550 read_only/backup/january
$ls –l
total 4
drwxr-xr-x 2 ken users 4096 Jan 24 12:50 backup
drwxr-xr-x 3 ken users 4096 Jan 24 12:51 read_only
$ ls -l read_only/backup
total 4
dr-xr-x--- 2 ken users 4096 Jan 24 12:51 january
mode的值将在“第15章 外壳脚本的安全”中的chmod命令进行讨论,可是当使用—parents开关,--mode只对列表中的最后一个目录有影响。
命令rmdir(remove directory)删除一个目录。这个目录必须是空的。它有两个开关:
n --ignore-fail-on-non-empty——当删除的目录中有文件时,不不报告错误。
n --parents(-p)——删除所有的父目录及子目录。
$ rmdir read_only
rmdir: read_only: Directory not empty
$ rmdir --parents read_only/backup/january/
rm 命令永久性删除文件。如果文件是一个符号或硬链接文件,它删除链接而不是文件本身。
$ rm old_notes.txt
$ ls old_notes.txt
ls: old_notes.txt: No such file or directory
rm命令有几个开关:
n --directory(-d)——删除目录
n --force(-f)——不提示用户并忽略不存在的文件
n --interactive(-i)——总是提示用户
n --recursive(-r或-R)——删除所有子目录中的内容
同时使用—recursive和—force开关将删除所有包含的文件和子目录,并不会有警告信息。你需要自己确保删除文件的正确性。
有些Linux的发行版使用—interactive开关作为缺省值,因此rm命令将会得到你的确认后才会删除指定的文件。
$ rm --interactive old_notes.txt
rm: remove ‘old_notes.txt’? y
$
通常rm不会删除目录但是使用了—recursive开关,它将删除任何包含的目录。
cp命令将文件从一个地方拷贝到另一个地方。如果参数文件最后列出的是一个目录。copy命令将所有的文件拷贝到这个目录。
有许多copy的开关——本章的结尾有完整的引用列表。一些通用的开关如下所示:
n --force(-f)——不提示用户;总是覆盖
n --interactive(-i)——总是提示用户
n --link(-l)——建立硬连接而不是拷贝
n --parents(-P)——增加源路径到目标路径
n --recursive(-R)——拷贝任何子目录
n --symbolic-link(-s)——建立符号链接文件而不是拷贝
n --update(-u)——覆盖旧文件或拷贝不存在的文件
$ cp notes.txt old_notes.txt # copying
$ mkdir backup
$ cp old_notes.txt backup
$ ls backup
old_notes.txt
和rm命令一样,有些Linux发行版中的copy命令缺省有—interactive开关,提示文件将会被覆盖。
$ cp --interactive project_notes.txt old_notes
cp: overwrite ‘old_notes/project_notes.txt’? n
$
mv(move)命令用来移动文件或更改文件名。象copy命令一样先将文件拷贝到另一个地方,但是mv命令会删除原始文件。mv命令也可以用来在相同目录中的文件进行改名。
$ mv notes.txt project_notes.txt # renaming
mv通用的开关如下所示:
n --backup(-b)——在覆盖现存的文件时会将现存的文件名加一个~字符,来备份现存的文件。
n --force(-f)——不提示用户;总是覆盖
n --interactive(-i)——覆盖前总是提示用户
n --update(-u)——覆盖旧的文件或拷贝不存在的文件
没有—recursive开关,当使用move命令移动一个目录时,它自动移动目录和目录所包含的内容。
namei(name inode)命令列出一个路径中所有的成分,包含符号连接。
$ namei files
f: files
l files -> /home/ken/bash/scripts
d /
d home
d ken
d bash
d scripts
本例中文件名files是一个符号链接。在这个链接路径中的每一个目录使用字符d进行标识,字符设备使用字符c进行标识,符号链接文件使用字符l进行标识,socket文件使用字符s进行标识,块设备使用b进行标识,常规文件使用字符-进行标识,?表示在路径中访问一个文件出错。
完整的文件许可模式可以使用-m(mode)开关显示,也可以使用ls –l看到。
对用户的操作

有几个命令可以查看谁登陆到计算机上了,他们在做什么?
finger命令显示显示了谁在计算机上,并提供了一些其他信息,包括他们的会话已经空闲了多长信息已经他们的联系信息。
$ finger
Login Name TTY Idle When Bldg. Phone
dhu Dick Hu *p6 4:25 Thu 14:12 4th Floor ext 2214
mchung Michael Chung *con 5:07 Fri 09:57 OS Support ext 1101
bgill Biringer Gill *p7 15 Fri 13:32
基于安全的考虑(访问finger’s.plan文件的权限),一些Linux版本不再包含finger命令。阅读finger手册页可以获取更多的信息。
还有一些其他的命令有类似的功能。users命令显示了一份登陆名的列表。
$ users
bgill dhu mchung
who命令显示了谁在计算机上,他们使用的连接是什么,它们在哪里登陆的。
$ who
dhu ttyp6 Mar 29 14:12
mchung console Apr 6 09:57
bgill ttyp7 Apr 6 13:32
w命令提供了更多的信息,包含系统状态统计和用户当前正在使用什么程序。
$ w
3:18pm up 9 days, 20:33, 3 users, load average: 0.64, 0.66, 0.64
User tty login@ idle JCPU PCPU what
dhu ttyp6 2:12pm 4:28 8:01 8:01 csh
mchung console 9:57am 5:10 sh
bgill ttyp7 1:32pm 19 bash
外壳脚本命令的别名

alias是命令的短格式。内置命令alias建立了当前Bash会话的缩写。为了建立一个别名,使用alias命令将一个命令和它的开关分配给一串字符。
$ alias lf=’ls -qFl’
$ lf
-rw-r----- 1 kburtch devgroup 10809 Apr 6 11:00 assets.txt
-rw-r----- 1 kburtch devgroup 4713 Mar 9 2000 mailing_list.txt
打印alias命令本身或加上“-p”开关,列出当前的使用别名的命令
$ alias
alias lf=’ls -qFl’
Bash只解释别名一次,别名允许使用命令本身作为别名。
$ alias ls=’ls -qF’ # Bash isn’t confused
通常只检查命令的第一个单词是否为别名,如果,上一个字符是空格,Bash也检查命令中的下一个单词是否也是别名。
使用别名后就不可以使用参数了,如果要使用参数,需要更强大的脚本命令。
内置命令unalias可以删除一个别名,开关“-a”则删除所有的别名。
大部分发行的Linux版本都使用别名定义一些通用的命令。例如:dir通常是ls的别名。还有一些命令给rm –i定义别名,迫使用户删除文件时进行提示。但是一些有经验的Unix程序员在使用这些命令时可能引起混乱,他们通常关闭这些功能。使用unalias命令删除它们不想要的别名。
和外壳脚本一起使用别名可能会导致混乱,因为别名只在脚本被按行读取时才进行扩展。如果别名使用在脚本函数中,脚本函数在定义时就进行扩展,而不是等到它们执行时。因此,最好不要在外壳脚本中使用别名。可是,你也可以在脚本中使用shopt –s expand_aliased命令打开别名的使用。
Bash的哈希表

当执行一个命令而没有指定路径时,外壳程序查找这个命令(在PATH变量中指定的目录)。找到这个命令之后,外壳程序将命令的位置保存在hash table(哈希表)中。之后,再次运行此命令时,Bash在表中查找命令的位置而不是再次搜索此命令,从而更快的执行命令。可是,当Bash记录了命令的位置之后,命令的位置被移动了,外壳就找不到这个命令了。
内置hash命令维护着哈希表。不使用任何开关,hash列出内存中的命令、它们的位置、会话期命令执行的次数。
$ hash
hits command
1 /bin/ls
1 /bin/uname
1 /usr/bin/tput
1 /bin/stty
1 /usr/bin/uptime
1 /usr/bin/man
如果后面跟了一个命令,Bash会查找这个命令的新位置。例如,你创建了一个命令ls,保存在当前的目录,PATH变量设定了当前目录优先使用,hash ls命令首先找到你自己建立的ls命令,使用./ls替代/bin/ls。
$ hash ls
$ hash
hits command
1 /bin/touch
0 ./ls
1 /bin/chmod
“-p”(path)开关显示的设定命令的路径。“-d”(delete)开关删除某个条目,“-r”(remove)清除hash表,删除所有的命令。“-t”(table)开关列出指定命令的路径。“-l”(list)以某种格式列出命令使hash命令可以重新使用它们。
$ hash -t ls less
ls /bin/ls
less /usr/bin/less
自定义提示符

虽然一些发行版使用不同的符号,但是缺省的Bash提示符是一个美元符号($)。大部分Linux的发行版重新定义提示符,以便可以包含一些额外的信息,例如你的登陆名和计算机名,当你在不同的计算机上使用不同的账户时,这是非常有用的。
如果PS1(prompt string 1)的变量名已经定义了,Bash将使用这个值作为你的提示符。如果你在这个字符串包含了变量名,Bash将使用变量替换你的提示符。
$ declare -x PS1=”Bash $ “
Bash $ pwd
/home/kburtch/archive
Bash $
下面命令声明了声明了一个三行的提示符,其中包含了一个空行、当前目录、先前的当前目录和登录名和计算机名,还有一个粗体的$.
$ declare -x PS1=”
/$PWD (/$OLDPWD)
/$LOGNAME@’uname -n’/[‘tput bold’/] /$ /[‘tput rmso’/]”
/home/kburtch/archive (/home/kburtch/work)
kburtch@linux_box $
/[和/]将显示格式字符括起来,格式字符通过tput命令返回。否则,Bash认为所有的字符都是显示的,而不能正确的区分这串长字符串。
Bash还有PS2变量,它是对多行未结束的命令的提示符,例如使用了多行的引用。缺省情况下,它是一个大于号“>”。
Bash在提示符中识别下列换吗字符:
n /a——A beep(ASCII钟的字符)
n /A——24小时的时间格式HH:MM
n /d——时间格式“星期-月-日”
n /D[s]——使用格式字符串s运行C语言的statftime函数
n /e——ASCII的退出字符
n /h——主机名
n /H——完整的主机名包含域名
n /j——在作业表中的作业号
n /l——tty设备
n /n——新行
n /r——回车
n /s——外壳名
n /t——24小时格式的时间
n /T——12小时格式的时间
n /@——AM/PM格式的时间
n /u——用户名
n /v——Bash的版本
n /w——当前的工作目录
n /W——当前工作目录的基本名
n /!——命令历史表的正向命令
n /#——会话的序列命令号
n /$——缺省提示符(超级用户使用#,否则使用$)
n /nnn——ASCII字符的八进制格式
n //——A斜杠
n /[——不可显示字符的开始
n /]——不可显示字符的结束
第五章将会详细讨论变量。你可以使用peomptvars外壳选项来关闭变量替换。
长命令行

如果命令过长,Bash自动滚动屏幕,例如:输入命令时光标到了窗口的右边,Bash自动切换到下一行。
如果你想将一个命令分成多行显示,你需要在一行的结尾使用斜杠(/)。Bash会在下一行显示提示符,通常是一个“>”,表示先前的行还没有结束。
$ printf “%s/n” “This is a very long printf. How long is it?/
> It’s so long that I continued it on the next line.”
This is a very long printf. How long is it? It’s so long that I continued it on
the next line.
自定义命令行的编辑

bind命令使你可以更改编辑键、编辑选项、以及建立键盘宏命令。更改只影响当前的编辑模式。
“-p”和“-P”开关显示了不同命令行的编辑功能——激活不同的键盘组合。“-P”以容易阅读的方式进行显示。
$ shopt -o emacs
emacs on
$ bind -P | head -5
abort can be found on “/C-g”, “/C-x/C-g”, “/e/C-g”.
accept-line can be found on “/C-j”, “/C-m”.
alias-expand-line is not bound to any keys
arrow-key-prefix is not bound to any keys
$ shopt -s -o vi
$ bind -P | head -5
abort is not bound to any keys
accept-line can be found on “/C-j”, “/C-m”.
alias-expand-line is not bound to any keys
arrow-key-prefix is not bound to any keys
使用“-m”(keymap)开关可以设定特定的编辑模式。
$ bind -P -m vi | head -5
abort can be found on “/C-g”.
accept-line can be found on “/C-j”, “/C-m”.
alias-expand-line is not bound to any keys
arrow-key-prefix is not bound to any keys
特殊字符可以使用斜杠“/”来表示。这些特殊字符是有emacs文本编辑器器所使用的。
n //——一个斜杠
n /”——一个双引号
n /’——一个单引号
n /a——一个报警(bell)
n /b——后退一格
n /c——Ctrl键
n /d——删除
n /e——退出键
n /f——换页
n /M——emacs的meta键
n /n——换行键
n /r——回车键
n /t——水平tab键
n /v——垂直tab键
n /nnn——八进制的ASCII码
n /xnnn——16进制的ASCII码
例如:control-g由/C-g来表示。
“-l”(list)开关列出所有可能的键盘功能。
$ bind -l | head -5
abort
accept-line
alias-expand-line
arrow-key-prefix
backward-char
为了看到某个特定的功能使用“-q”(query)开关。
$ shopt -s -o emacs
$ bind -q abort
abort can be invoked via “/C-g”, “/C-x/C-g”, “/e/C-g”.
使用“-u”开关可以删除某个绑定。如果由不止一个绑定,只删除第一个。
$ bind -u abort
$ bind -q abort
abort can be invoked via “/C-x/C-g”, “/e/C-g”
“-r”(remove)可以删除指定的绑定。
$ bind -r “/e/C-g”
$ bind -q abort
abort can be invoked via “/C-x/C-g”.
你也可以使用组合键、冒号和编辑功能名来增加一个新的绑定。例如:backward-kill-line功能用来删除从行的开始到光标所在位置的所有字符。在vi模式,backward-kill-line通常并没有绑定到任何组合键上。
$ shopt -s -o vi
$ bind -q backward-kill-line
backward-kill-line is not bound to any keys.
下面示范了如何将backward-kill-line功能绑定到一个组合键上。
$ bind “/C-w:backward-kill-line”
$ bind -q backward-kill-line
backward-kill-line can be invoked via “/C-w”.
现在control-w可以从行的开始处删除字符了。
除了上面的功能外,还有一些选项或变量。“-v”和“-V”开关显示这些键盘设置的选项。“-V”选项以更容易理解的方式显示。
$ bind -v | head -5
set blink-matching-paren on
set completion-ignore-case off
set convert-meta on
set disable-completion off
set enable-keypad off
$ bind -V | head -5
blink-matching-paren is set to ‘on’
completion-ignore-case is set to ‘off’
convert-meta is set to ‘on’
disable-completion is set to ‘off’
enable-keypad is set to ‘off’
这些选项可以打开或关闭,如下所示:
$ bind “set enable-keypad on”
$ bind -V | head -5
blink-matching-paren is set to ‘on’
completion-ignore-case is set to ‘off’
convert-meta is set to ‘on’
disable-completion is set to ‘off’
enable-keypad is set to ‘on’
所有有效的功能和选项的列表参考Readline手册页的内容。
bind命令也可以定义键盘宏命令。将一些长命令定义为短的组合键,从而减少输入量。“-s”和“-S”开关列出当前定义的宏命令。“-V”开关是更人性化的阅读方式。
建立宏命令的格式和分配功能的格式一样,除了“/””必须包含要扩展的文本。
$ bind -S
$ bind “/C-w:/” >/dev/null/””
$ bind -S
/C-w outputs >/dev/null
Control-w将插入“>dev/null”到当前行。
你自己的会话配置文件

当你登陆到一台计算机上并开始一个新的会话,你也许需要输入几个命令来配置你的会话环境。也许你想将编辑环境从emacs改为vi、建立新的键绑定或更改你的命令提示符。如果你将这些配置保存在一个特定的文件,Bash将在你每次登陆是运行这些命令,而不是你每次自己输入这些命令。这些文件称之为profile file,它包含你自己定义的命令来适合你的会话。
最初的Bourne外壳在用户登陆时运行两个配置文件。第一个称之为“/etc/profile”,它是一个通用的配置文件,适合所有的用户。第二个是“.profile”,他保存在用户的主目录中,可以包含每个用户特定的配置信息。Bash开始于sh时模仿了这种行为。
Bash扩展了运行几个依赖于环境的配置文件的原则,此外,Linux发行版经常自定了配置文件来运行保存在其他脚本中的命令。
Bash能区分登陆会话和其他实例。当用户或程序首先登陆或使用Bash的“—login”来模拟登陆时,Bash作为登陆外壳运行。一个登陆外壳并不须给用户提供一个提示符。它只表示Bash在当前会话中是一个上面的程序,当Bash运行完,登陆会话也结束了。
当你在登陆外壳中,login_shell外壳选项打开。这个选项用于验证你是否在登陆外壳中。
$ shopt login_shell
login_shell on
当Bash开始时没有使用脚本或使用了-i开关,Bash作为interactive shell(交互外壳程序)来运行。交互外壳给用户提供了提示符。交互外壳程序不必是登陆外壳程序。用户可以通过在Bash提示符下打印Bash来运行一个非登陆的交互外壳程序。使用这种方法,Bash将命令从更多通用目的的命令中分离出用于自定义交互会话的命令。
“/etc/profile”文件包含了设置命令,适用于所有用户的环境。通用的配置文件跟下面的示例文件差不多:
#!/etc/profile
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
# HOSTNAME is the result of running the hostname command
declare –x HOSTNAME=`/bin/hostname`
# No more than 1000 lines of Bash command history
declare –x HISTSIZE=1000
# If PostgreSQL is installed, add the Postgres commands
# to the user’s PATH
If test –r /usr/bin/pgsql/bin ; then
declare –x PATH=”$PATH””:/usr/bin/pgsql/bin”
fi
# end of general profile
只有超级用户可以编辑这个文件。当Bash用作登陆外壳时,他执行的第一个文件可以叫做“~/.bash_profile”,“~/.bash_login”,“~/.profile”。当会话完成,如果有“~/.bash_logout”文件,Bash运行它。
例如:SuSE Linux运行“~/.profile”作为用户的配置文件。你可以查看你的主目录是否有这个文件。通过编辑这个文件,你可以增加你想在登陆时执行的命令。
# My profile
shopt -s -o emacs # I prefer emacs mode to vi mode
date # display the date when I log on
通过使用“-login”开关来模拟登陆并测试上面的更改。
$ bash --login
Wed Feb 6 15:20:35 EST 2002
$ shopt -o emacs
emacs on
$ logout
不登陆而运行一个新的Bash交互会话,系统将不会运行配置文件。
$ bash
$ logout
bash: logout: not login shell: use ‘exit’
$ exit
如果配置文件脚本不能正常运行,系统叫从BASH_ENV环境变量查找相应的脚本进行执行,BASH_ENV通常包含了要执行的文件和路径。可是,你应尽量避免使用BASH_ENV变量。给一组脚本设置通用环境通常使用source命令来完成,此命令在第14章进行讨论。BASH_ENV在交互会话中没有效果。
你可以通过使用“—noprofile”开关来停止登陆脚本的运行。Bash在交互会话中运行不同的配置文件,在外壳会话中也适用不同的配置文件。Bash在文件“~/.bashrc”中寻找自定义脚本并执行它们,而不是使用登陆配置文件。别名功能只允许使用在资源文件中。一个不同的资源文件可以使用“—init-file”或“—rcfile”开关来指定。典型的资源文件如下所示:
# /etc/bashrc
# Don’t let others write to the user’s files
umask 002
# Alias ls to provide default switches
alias ls=’ls –qF’
一些发行版增加了几行代码到你的登陆配置文件中,它们用来运行“~/.bashrc”文件中的命令。这不是Bash的特性,而是Linux发行版所做的更改。你可以增加下面几行代码来测试“~/.bashrc”是否运行了。
# My bashrc Resource File Customizations
printf “%s/n” “.bashrc has run”
在命令提示符下开始一个新的会话来测试上面的代码。SuSE Linux的运行结果总是如下所示:
$ bash --login
.bashrc has run
$ logout
$ bash
.bashrc has run
$ exit
最终,你只有通过测试你自己的Linux发行版才能知道是否包含了资源文件。
资源文件可以使用“--norc”开关来禁止运行。
某些发行版还可以在登陆时运行其他的文件:
n Red Hat和Mandrake Linux将你的自定义、功能和别名分开放在“~/.bashrc”,而其他的设置放在“~/.bash_profile”文件中。后面的文件将自动运行前面的文件(如果前面的文件存在的话)。
n SuSE Linux将你的自定义、功能和别名分开存在“~/.bashrc”文件中,其他的自定义保存在“~/.profile”文件中。后面的文件自动调用前面的文件(如果前面的文件存在的话)。
n SCO Linux(也称之为Caldera Linux)使用“~/.profile”,它调用“~/.bashrc”文件。它接着运行“/etc/config.d/shells”来配置系统的缺省值。当“~/.bashrc”运行时,它调用“/etc/config.d/shells/bashrc”来设置非交互的缺省值。用户的自定义保存在“~/.profile-private”和“~/.bashrc-private”文件中。
同样,通用配置文件也可以自定:
n Red Hat和Mandrake也将自定义分为“/etc/bashrc”和“/etc/profile”来模仿用户配置文件的行为。
n SuSE Linux自动设置“/etc”中的多个文件中内容,包含“/etc/profile”。最终,用户更改必须保存在分开的文件称之为“/etc/profile.local”,当系统升级或重新配置时,这些配置会丢失的。其他的系统脚本自动执行“/etc/SuSEconfig”文件,已安装的软件包保存在“/etc/profile.d”的脚本文件中。SuSE也包含了“/etc/profile.dos”脚本用来定义来自MS-DOS系统的用户。这些通过SuSE的配置软件来设定,但是他也可以从“/etc/profile.local”文件中执行。
n SCO Linux只在“/etc/profile”文件中放置最小的和最通用的设置信息来设定Bourne-based脚本。通用的Bash设置保存在“/etc/config.d/shells/profile”和“/etc/config.d/shells/bashrc”文件中。保存在“/etc/profile.d”文件中的脚本是为了自动执行系统已安装的软件包。
命令参考

ls命令的开关

n --all(or –a)——显示所有的文件包含“.”和“..”。
n --almost-all(或者-A)——除了“.”和“..”两个文件显示所有的文件
n --block-size=n——以n字节为单位来显示文件的大小
n --classify(或者-F)——显示文件名时增加一个符号来表示它的类型
n --color=t——使用颜色来表示文件名,t=never、always和auto。
n --dereference(或-L)——显示有符号链接引用的项目
n --directory(或者-d)——显示目录的信息而不是目录的内容
n --dired(或者-D)——使用emacs dired模式输出
n --escape(或者-b)——显示八进制的退出码。
n --file-type(或者-p)——和--classify一样
n --format=across(或者-x)——根据行来排序
n --format=commas(或者-m)——使用逗号来吧文件名分开
n --format=long(或者-l)——显示文件的明细的列表
n --format=single-column(或者-l)——每行显示一个文件
n --format=verbose——和long格式相同
n --format=vertical(或者-C)——所有文件一列
n --full-time——显示时间和日期的全格式。
n --hide-control-chars(或者-q)——不可显示的文件名以问号来显示
n --human-readable(或者-h)——以千字节为单位来显示文件的大小
n --ignore=p(或者-I)——忽略匹配模式p的文件
n --ignore-backups(或者-B)——不显示以~结尾的文件
n --indicator-style=classify——和--classify一样
n --indicator-style=none——不对文件进行分类
n --indicator-style=file-type——和—file-type开关一样
n --inode(或者-i)——显示文件的节点号
n --kilobytes(或者-k)——以1024字节为单位显示文件的大小
n -f——不排序,开启-aU,关闭-lst
n --literal(或者-N)——显示不可打印字符,和-q开关类似
n --no-group(或者-G)——隐藏文件的组名
n --numeric-uid-gid(或者-n)——显示UID和GID号码,而不是名字。
n -o——显示长列表,而不显示组属性
n --quote-name(或者-Q)——以双引号将文件名封闭起来
n --quoting-style=literal——和—literal一样
n --quoting-style=local——使用本地引用风格封闭单独的文件名
n --quoting-style=shell——使用外壳引用封闭单独的文件名
n --quoting-style=shell-always——总是使用外壳引用封闭单独的文件名
n --quoting-style=c——使用C语言的字符串格式封闭文件名
n --quoting-style=escape——使用斜杠表示退出字符
n --recursive(或者-r)——和排序的顺序相反
n --recursive(或者-R)——显示子目录中的内容
n --si(或者-h)——和—human-readable类型,但是以1000为单位而不是1024
n --size(或者-s)——显示文件的大小
n --sort=size(或者-S)——根据文件的尺寸进行排序
n --sort=extension(或者-X)——根据文件的后缀进行排序
n --sor=none(或者-U)——根据文件保存在目录的顺序进行排序
n --sort=time(或者-t)——根据时间进行排序。缺省时,--time=ctime
n --sort=version(或者-v)——考虑到GNU的版本号,根据字符顺序进行排序。
n --time=atime(或者-u)——根据访问时间排序
n --time=access——和上面一条相同
n --time=use——和ctime相同
n --time=ctime(或者-c)——显示变更时间:如果有-t,根据更改时间进行排序
n --time=status——和ctime相同
n --tabsize=n(或者-T)——假定Tab停止在每n个字符,而不是8个字符。
n --width=n(或者-w)——假定屏幕是n个字符宽度而不是屏幕的实际值
printf格式码

n %b——扩展斜杠序列
n %c——显示一个字符
n %d——显示有符号数
n %e——显示浮点数,使用科学计数法
n %f——显示浮点数
n %g——根据变量的值,选择%f和%e
n %i——和%d相同
n %o——显示八进制数
n %q——应用一个字符串,以便它可以被外壳脚本正确的读写
n %s——显示未引用字符串
n %u——显示无符号数
n %x——显示无符号16进制数据,使用小写字符
n %X——显示无符号16进制数,使用大写字符
n %%——显示百分号“%”
printf的斜杠引导的代码

n /b——后退一个
n /f——换页
n /n——换行
n /r——回车
n /t——Tab
n /v——垂直Tab
n /’——单引号字符(为了兼容C语言)
n //——斜杠
n /0n——n是一个八进制数表示一个8位的ASCII字符
rm命令开关

n --directory(或者-d)——删除目录
n --force(或者-f)——不提示用户并忽略缺少的文件
n --interactive(或者-i)——总是提示用户
n --recursive(或者-r或-R)——删除子目录中的内容
cp命令开关

n --archive(或者-a)——和-dpR相同
n --backup(或者-b)——在更改文件之前备份要修改的文件,备份文件名使用~开头
n --backup=none/off——不使用编号备份
n --backup=numbered/t——使用编号备份
n --backup=existing/nul——如果文件已经存在使用编号备份,否则使用波浪号
n --backup-simple/never——总是使用波浪号备份
n --no-dereference(或者-d)——保存链接
n --force(或者-f)——不提示用户,总是覆盖文件
n --interactive(或者-i)——总是提示用户
n --link(或者-l)——建立硬链接而不是拷贝文件
n --preserve(或者-p)——必要的话保留文件的属性和拥有者
n --recursive(或者-R)——拷贝所有的子目录
n -r——和上面一条类似,但是不包含管道文件的特殊处理和不能正确拷贝的文件
n --sparse=w——裁剪稀疏文件(w=never),完全建立稀疏文件(w=always),根据命令做出裁剪(w=auto)
n --strip-trailing-slashes——从要拷贝的文件名的路径中删除尾部的斜杠
n --symbolic-link(或-s)——建立一个符号链接而不是拷贝文件
n --suffix=s(或者-S s)——使用新的后缀字符串s替换路径后缀
n --target-directory=d——拷贝文件到目录d中
n --update(或者-u)——覆盖旧的文件或拷贝缺少的文件
n --one-file-system(或者-x)——留在当前的文件系统中
mv命令开关

n --backup(或者-b)——删除文件前,使用~加文件名的文件备份要删除的文件
n --backup=none/off——不使用编号备份
n --backup=numbered/t——总是使用编号备份
n --backup=existing/nul——如果文件存在使用编号备份,否则使用波浪号备份
n --backup=simple/never——总是使用波浪号备份
n --force(或者-f)——从不提示用户,总是覆盖
n --interactive(或者-i)——总是提示用户
n --strip-trailing-slashes——将要拷贝的文件的路径名尾部的斜杠删除
n --suffix=s(或者-S)——使用新的后缀字符串替换路径后缀
n --target-directory=d——拷贝文件到目录d中
n --update(或者-u)——覆盖旧的文件或拷贝缺少的文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux 显示器 计算机