【Linux命令】《鸟哥Linux基础》第十章 认识与学习BASH

第十章 认识与学习BASH

10.1 Bash与Shell

命令别名设置功能:

alias lm='ls -al'    给命令ls -al一个别名lm。注意,等号两端不能有多余空格

查询命令是否是Bash shell的内置命令:type

type [-tpa] name
		-t  此时,file表明命令为外部命令;
			alias表明命令是命令别名设置的命令;
			builtin表明该命令为bash内置的命令功能
		-p  如果后面接的name是外部命令时,才会显示完整文件名
		-a  会有PATH变量定义的路径中,将所有含有name的命令都列出来,包含alias

命令的执行与快速编辑按钮:

使用反斜线+回车: \+[Enter]  能够让命令换行输入

Ctrl + u  从光标向前删除命令串
Ctrl + k  从光标向后删除命令串

Ctrl + a  让光标移动到整个命令串的最前面
Ctrl + e  从光标移动到整个命令串的最后面

10.2 Shell的变量功能

10.2.1 变量概念

变量,让某一个特定的字符串代表不固定的内容。

变量具有可变性,使用方便。

影响bash环境操作的变量,PATH,HOME,MAIL,SHELL。

10.2.2 变量的使用基础

变量的使用与设置:

echo $variable   显示变量代表的内容
echo $PATH       显示PATH变量的内容
echo ${PATH}     同上,显示PATH变量的内容


设置变量:
[dj@study ~]$ echo ${myname}        此时myname变量是不存在的,是空的;不要随便显示一个不存在的变量,其他的shell中可能会报错

[dj@study ~]$ myname=dj             将myname设置为dj,等号两边不能有空格
[dj@study ~]$ echo ${myname}        输出myname
dj




变量设置规则:
var双引号内的特殊字符,保留原本的特性
单引号内的特殊字符,仅为一般字符(纯文本)

[dj@study ~]$ var="lang is $LANG"      	双引号
[dj@study ~]$ var2='lang is $LANG'		单引号

[dj@study ~]$ echo $var					双引号中的特殊字符,是特殊含义
lang is zh_CN.UTF-8

[dj@study ~]$ echo $var2				单引号中的特殊字符,是普通文本
lang is $LANG



获得内核版本:
[dj@study ~]$ version=$(uname -r)
[dj@study ~]$ echo $version
3.10.0-1062.el7.x86_64



累加变量内容:
PATH=$PATH:/home/bin
或者:
PATH="$PATH":/home/bin
或者:
PATH=${PATH}:/home/bin

若该变量需要在其他子程序中智行,需要使用 export 使变量变成环境变量:
export PATH



取消myname变量:
unset myname    

export可以使父进程中定义的变量在子进程中生效:

name=dj
echo $name   	输出dj

bash			进入子进程
echo $name 		输出空
exit			退出子进程

export name		使name变量生效!!!这样就可以在其他进程中生效

bash			进入子进程
echo $name 		这次可以输出dj
exit			退出子进程

进入你目前内核的模块目录:先获取当前的内核版本,输入到路径名称中组合成完整路径名

cd /lib/modules/`uname -r`/kernel		两法功能相同
cd /lib/modules/$(uname -r)/kernel		该法更优

先用locate将文件名数据列出来,再用ls输出详细信息:

[dj@study kernel]$ ls -ld $(locate crontab)
-rw-------. 1 root root   541 8月   9 2019 /etc/anacrontab
-rw-r--r--. 1 root root   451 6月  10 2014 /etc/crontab
-rwsr-xr-x. 1 root root 57656 8月   9 2019 /usr/bin/crontab
drwxr-xr-x. 2 root root    21 4月  29 21:33 /usr/share/doc/man-pages-overrides-7.7.3/crontabs
-rw-r--r--. 1 root root 17738 8月   9 2019 /usr/share/doc/man-pages-overrides-7.7.3/crontabs/COPYING
-rw-r--r--. 1 root root  2626 8月   9 2019 /usr/share/man/man1/crontab.1.gz
-rw-r--r--. 1 root root  4229 6月  10 2014 /usr/share/man/man1p/crontab.1p.gz
-rw-r--r--. 1 root root  1121 6月  10 2014 /usr/share/man/man4/crontabs.4.gz
-rw-r--r--. 1 root root  1658 8月   9 2019 /usr/share/man/man5/anacrontab.5.gz
-rw-r--r--. 1 root root  4980 8月   9 2019 /usr/share/man/man5/crontab.5.gz
-rw-r--r--. 1 root root  2566 8月   9 2019 /usr/share/vim/vim74/syntax/crontab.vim

简化工作目录路径查找:

work="/home/dj/dingjing/darknet"
cd $work

10.2.3 环境变量的功能

列出目前的shell环境下的所有环境变量与其内容:

env
或:
export
echo $RANDOM										输出随机数值
declare -i number=$RANDOM*10/32768;echo $number   	输出0-9之间的数值

修改终端命令开头的提示符:

[dj@study ~]$ cd /home
[dj@study home]$ PS1='[\u@\h \w \A #\#]\$'
[dj@study /home 13:39 #22]$

恢复回去:
[dj@study /home 13:39 #22]$PS1='[\u@\h \W]\$'
[dj@study home]$

写CSDN博客时,常常会复制命令行的命令和执行结果到CSDN的bash代码段中,那个井号键每次都会被作为注释符,将该行后面的有效内容注释掉,PS1='[\u@\h \W]$',将井号键修改成美元符号:

[root@study ~] PS1='[\u@\h \W]$ '				结尾最好带个空格		
[root@study ~]$

但是这只是一时的,登出后,在进入root环境,又变成老样子井号键,可以写入root的环境配置文件:

[root@study ~] vim ~/.bashrc
PS1='[\u@\h \W]$ '								把这句加进去



[root@study ~]$ cat ~/.bashrc					加入后整个文件内容如下
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi
PS1='[\u@\h \W]$ '		




[root@study ~] source ~/.bashrc					让文件生效




[root@study ~]$ exit
登出
[dj@study ~]$ su -
密码:
上一次登录:,,,,
[root@study ~]$ 								登出后再进入还是OK的

美元符号$,本身就是个变量,代表目前这个shell的进程号(PID):

echo $$   得到当前shell的PID号码

问号?,本身也是个变量,能够获得【上个命令】的【返回值】:

[dj@study home]$echo $SHELL		正确执行
/bin/bash
[dj@study home]$echo $?			返回0
0
[dj@study home]$12name=dj		错误执行
bash: 12name=dj: 未找到命令...
[dj@study home]$echo $?			返回非0
127
[dj@study home]$echo $?			上个命令正确执行,返回0
0

较高级的硬件通常会向下兼容老版本的软件,但是较高级的软件可能无法在旧机器上安装。

export:自定义变量转换成环境变量
env和set差异在于,该变量是否会被子进程所继续引用。
子进程仅会继承父进程的环境变量,子进程不会继承父进程的自定义变量。
为了让父进程中的自定义变量,能用在子进程中,使用export将其变成环境变量:

export 父进程中的自定义变量

10.2.4 影响显示结果的语系变量(locale)

修改语系时,主要修改两个变量:LANG 和 LC_ALL

locale -a  		查看支持的语系种类

cat /etc/locale.conf  整体系统默认的语系定义在/etc/locale.conf中


暂时修改中文语系为英文语系:
locale								显示一下看看
LANG=en_US.utf8;locale				设置LANG
export LC_ALL=en_US.utf8;locale		设置LC_ALL

10.2.5 变量的有效范围

就是父进程中的环境变量可以被子进程所引用;父进程中的自定义变量却不能。

这涉及内存配置的原因:
(1)启动一个shell的时候,系统分配一块内存给这个shell用,这块内存中的变量可以给子进程使用;
(2)父进程利用export功能,将自定义变量的内容写入到这块内存区域(环境变量);
(3)在加载另一个shell的时候(即离开父进程,启动子进程),子shell可以将父shell的环境变量所在内存区域导入自己的环境变量区块中。

10.2.6 变量的键盘读取、数组与声明:read、array、declare

read [-pt] variable
		-p 后面可以接提示字符
		-t 后面可以接等待的秒数,不会一直等待使用者



读入用户输入的一个自定义变量atest:
[dj@study home]$read atest
this is a test
[dj@study home]$echo ${atest}
this is a test



等待10秒钟的时间,将用户输入的信息保存为自定义变量named中;
但是,如果超过10s没有输入,相当于输入了空字符串!
[dj@study home]$read -p "please input your name:" -t 10 named
please input your name:dj
[dj@study home]$echo ${named}
dj
declare [-aixr] variable
			-a  将后面名为variable的变量定义为数组array类型
			-i  将后面名为variable的变量定义为整数integer类型
			-x  用法同export,将后面的变量variable变成环境变量
			-r	将变量设置成为readonly类型,该变量不可被更改内容,也不能unset



以整数形式显示得到的结果:
[dj@study ~]$sum=10+20
[dj@study ~]$echo $sum
10+20
[dj@study ~]$declare -i sum=10+20
[dj@study ~]$echo $sum
30

默认情况下,bash会将变量类型默认为字符串;bash环境中的数值计算只能达到整数形态,1/3结果是0。如果需要非字符串的变量,就得进行变量声明。

declare -x sum      将sum声明成环境变量
export | grep sum   显示出来看看

declare -r sum     	让sum变成只读属性,不可修改;只能注销后再次登录才能恢复该变量的类型
sum=testing			会报错,提醒说这个变量不能修改!

declare +x sum		取消sum的环境变量资格,将其变成自定义变量
declare -p sum      -p可以单独列出变量的类型


[dj@study ~]$declare -p sum		
declare -irx sum="30"			本来是这个
[dj@study ~]$declare +x sum		取消其环境变量资格
[dj@study ~]$declare -p sum
declare -ir sum="30"			现在是这个

数组的使用:

var[index]=content  给数组中的指定下标的元素赋值

数组的赋值与显示:
[dj@study ~]$ var[1]="small ming"
[dj@study ~]$ var[2]="big ming"
[dj@study ~]$ var[3]="nice ming"
[dj@study ~]$ echo "${var[1]},${var[2]},${var[3]}"
small ming,big ming,nice ming

10.2.7 与文件系统及程序的限制关系:ulimit

ulimitbash用于限制用户的某些系统资源的,包括:
可以开启的文件数量;
可以使用的CPU时间
可以使用的内存总量等

ulimit [-SHacdfltu] [配额]
			-H  严格的设置,必定不能超过这个阈值
			-S  警告的设置(soft limit),可以超过该阈值,但是超过后会有警告信息,比-H的小,提前预警
			-a  后面不接任何选项或参数,可列出所有的限制额度
			-c  当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用),这就是内核文件,此项为了设置每个内核文件的最大容量
			-f  此shell可以建立的最大文件容量,单位kb,一般大小为2G
			-d  程序可以使用的最大段内存容量segment?
			-l  可用于锁定(lock)的内存量?
			-t  可食用的最大CPU时间,单位s
			-u  单一使用者可以使用的最大进程数量




列出你目前普通用户的所有限制数据的数值:
[dj@study ~]$ ulimit -a
core file size          (blocks, -c) 0              为0表示没设置
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited		可以建立的单一文件大小
pending signals                 (-i) 3756
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024			同时可以开启的文件数量
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3756
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited




限制使用者仅能建立10MB以下容量的文件:
ulimit -f 10240
ulimit -a | grep 'file size'

[dj@study ~]$dd if=/dev/zero of=123 bs=1M count=20  尝试建立一个20M的文件,失败了
文件大小超出限制(吐核)
[dj@study ~]$rm 123			   删掉这个失败的文件,必须注销后登录,才能解除10M的限制

10.2.8 变量内容的删除、取代、替换

删掉path中包含local/bin的部分:
从头到尾去查找,看看是否有  /*local/bin:  的内容,将找到的最短的一条匹配内容删掉:

[dj@study ~]$ path=${PATH}
[dj@study ~]$ echo ${path}
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin:/home/dj/bin
[dj@study ~]$ echo ${path#/*local/bin:}
/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin:/home/dj/bin




删除最短的符合要求的内容:(只有一个井号键#)
[dj@study ~]$ echo ${path#/*:}
/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin:/home/dj/bin

删除最长的符合要求的内容:(要有两个井号键##)
[dj@study ~]$ echo ${path##/*:}
/home/dj/bin




从后往前匹配:用百分号%
[dj@study ~]$ echo ${path%:*bin}   其实是删除了最后一个目录
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin

[dj@study ~]$ echo ${path%%:*bin}  其实是保留了第一个目录
/usr/local/bin
变量中的内容替换:

[dj@study ~]$ echo ${path/sbin/SBIN}		一个斜杠/只替换第一处匹配
/usr/local/bin:/usr/local/SBIN:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin:/home/dj/bin

[dj@study ~]$ echo ${path//sbin/SBIN}	两个斜杠//替换全部匹配
/usr/local/bin:/usr/local/SBIN:/usr/bin:/usr/SBIN:/bin:/SBIN:/home/dj/.local/bin:/home/dj/bin

小结:

变量设置方式说明
${变量#关键词}从头开始匹配,将符合的最短匹配删除
${变量##关键词}从头开始匹配,将符合的最长匹配删除
${变量%关键词}从后开始匹配,将符合的最短匹配删除
${变量%%关键词}从后开始匹配,将符合的最长匹配删除
${变量/旧字符串/新字符串}从头开始匹配,将第一个匹配的旧字符串替换
${变量//旧字符串/新字符串}所有匹配的旧字符串替换为新字符串
username=${username-root}     	如果username为空,输出root,否则输出本来的值;对于空字符串无能为力

username=${username:-root}		如果username为空或为空字符串,输出root


判断变量是否存在:
[dj@study ~]$ unset str;var=${str?novar}      	取消str变量;判断str变量是否存在
bash: str: novar								显然不存在,报了错
[dj@study ~]$ str="oldvar";var=${str?novar}		给str变量赋值,使其存在且非空;判断str变量是否存在,没有报错,说明str存在
[dj@study ~]$ echo "var=${var},str=${str}"		查看str变量
var=oldvar,str=oldvar

书本第333页的表格,内容太多了。想不起来就自行翻书吧。

10.3 命令别名与历史命令

10.3.1 命令别名设置:alias、unalisas

alias  						列出所有的命令别名

alias rm='rm -i'      		删除前询问
alias lm='ls -al| more'  	查看文件设置信息
alias vi='vim'				自动打开vim

alias cls='clear'			清屏
alias dir='ls -l'			列出目录和文件



unalias lm					取消lm='ls -al| more'的命令

10.3.2 历史命令:history

alias h='history'	输入h等于输入了history

history [n]			列出最近的n条命令
history [-c]		将目前的shell中所有history内容完全删除
history [-raw] histfiles	
			-r  将histfiles的内容读到当前这个shell的history记录中
			-a  将目前新增的history命令新增入histfiles中,若没有加入histfiles中,则默认写入~/.bash_history
			-w  将目前的history记录内容写入histfiles中



[dj@study ~]$ history 3			查看最近3条命令
  194  alias
  195  h
  196  h 3
[dj@study ~]$ history  -w		默认将当前历史命令写入~/.bash_history
[dj@study ~]$ echo ${HISTSIZE}	共有1000条历史命令
1000



!!     	两个感叹号,执行最近执行过的命令
!195	再次执行当前历史中的编号为195的那条命令
!al		执行最近以al为开头的命令

需要小心安全问题,尤其是root的历史记录文件,那是Cracker的主要攻击对象

同一个账号同时开启多个bash终端,这几个终端的身份都是root,存在~/.bash_history写入问题!
最后注销的那个bash才会是最后写入的数据,其他的终端内的bash命令就不会被记录(其实有被记录,只是被后来的最后一个bash所覆盖更新了)。

因此,尽量使用单一bash登录!!

强制更新记录文件:

history -c
history -w

10.4 Bash shell的操作环境

登录主机时,屏幕上的说明文字、登录时给予用户一些信息或欢迎文字、习惯的环境变量和命令别名等,希望能在登录的时候就设置好。系统全局设置、个人喜好设置,仅是一些文件放置的地点不同。

10.4.1 路径与命令查找顺序

基本顺序:

  1. 相对/绝对顺序执行命令,如/bin/ls 或 ./ls
  2. alias找到该命令来执行
  3. 由bash内置的命令(builtin)来执行
  4. 通过$PATH这个变量的顺序查找到的第一个命令来执行
[dj@study ~]$ alias echo='echo -n'
[dj@study ~]$ type -a echo
echo 是 `echo -n' 的别名
echo 是 shell 内嵌
echo 是 /usr/bin/echo
echo 是 /bin/echo

10.4.2 bash的登录与欢迎信息:/etc/issue、/etc/motd

[dj@study ~]$ cat /etc/issue
\S
Kernel \r on an \m
issue内代码意义
\d本地时间日期
\l小写的字母L,显示第几个终端界面
\m显示硬件的等级(i386、i486、i586…)
\n显示主机的网络名称
\O显示domain name
\r操作系统的版本(相当于uname -r)
\t显示本地端时间的时间
\S操作系统的名称
\v操作系统的版本

通过修改/etc/issue文件,按照需要的展示形式去展示。

使用telnet远程登录时看到的界面,是在/etc/issue.net文件中设置的。

想让用户登录后获取一些信息,例如你想要大家都知道的信息,那么可以将信息加入/etc/motd文件。例如当登录后告诉登录者,系统将会在某个固定时间进行维护工作(一定要是root的身份才能修改):

vim /etc/motd
写入需要展示的内容,保存退出。

10.4.3 bash的环境配置文件

10.4.3-1 输入用户名和密码——进入login shell——

(1)全局配置:主要读取/etc/profile

/etc/profile,这是系统的整体设计,会依序调用外部的配置文件——
/etc/profile.d/*.sh(主要是bash界面颜色、语系、各种命令别名设置等)——
/etc/locale.conf(主要是LANG和LC_ALL)——
/usr/share/bash-completion/completions/*(主要是【tab】键,命令补齐、文件名补齐、命令的选项和参数补齐等功能)

(2)个人配置:主要读取~/.bash_profile
在bash读完了整体环境设置的/etc/profile并借此调用其他配置文件后,接下来会读取用户的个人配置文件(其实只会依序读取下面3个文件中的1个,如果第一个不存在才去读取第二个)

~/.bash_profile~/.bash_login~/.profile

真正的调用可能是:
~/.bash_profile——~/.bashrc——/etc/bashrc

[dj@study ~]$ cat ~/.bash_profile		查看用户个人配置
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

由于$HOME/binPATH中,因此,将自己建立的执行文件放置到自己的家目录下的~/bin/目录,就可以直接执行该文件,免除输入绝对路径或相对路径的烦恼。

login shell环境下,最终被读取的配置文件是~/.bashrc这个文件。可以将自己的偏好设置写入该文件即可。

(3)source 读入环境配置文件
省的还得注销后再生效,这样可以直接写入shell中。

source configfilename

source ~/.bashrc	将家目录的.bashrc文件读入目前的bash环境中
. ~/.bashrc			同上
10.4.3-2 未输入用户名和密码——进入non-login shell——

仅会读取~/.bashrc而已

普通用户的~/.bashrc

[dj@study ~]$cat ~/.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

root用户的~/.bashrc

[root@study ~]# cat ~/.bashrc
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

这里,root用户,会继续调用/etc/bashrc文件,这个/etc/bashrc文件是RedHat系统特有的。

10.4.3-3 其他可能会影响bash操作的配置文件

(1)/etc/man_db.conf文件——规定了执行man的时候,该去哪里查看数据的路径设置。

如果以tarball方式安装软件,man page可能会放置在/usr/local/softpackage/man,其中softpackage是软件名称,应手动将该路径添加到/etc/man_db.conf文件。

(2)~/.bash_history文件——记录了历史命令。

每次登录bash后,会先读取这个文件,将所有历史命令读入内存。

(3)~/.bash_logout文件——记录了【当我注销bash后,系统再帮我做完什么操作后才离开】。

默认情况下,注销时,bash只是帮我们清屏。可以自行加入备份或其他重要任务。

10.4.4 终端的环境设置:stty、set

stty -a    查看目前环境中的按键列表

speed 38400 baud; rows 31; columns 138; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

如果不小心在vim中按了 Ctrl + c,界面锁死,可以按Ctrl + q 解锁。

组合按键执行结果
Ctrl + c终止目前的命令
Ctrl + d输入结束(EOF)
Ctrl + m回车
Ctrl + s暂停屏幕输出
Ctrl + q恢复屏幕输出
Ctrl + u在提示字符下,将整列命令删除
Ctrl + z暂停目前的命令

10.4.5 通配符与特殊符号

通配符意义
*0个到无穷多个任意字符
?一定有一个任意字符
[]一定有一个在括号内的字符(非任意字符)。如[abc]表示一定有一个字符,可能是a,b,c中的任何1个
[-]在编码顺序内的所有字符。[0-9]表示0-9之间的所有数字,因为数字的语系编码是连续的
[^]反向选择。[^abc]表示一定有一个字符,只要是非a,b,c的其他字符就接受
特殊符号意义
#注释
\转义符
|管道(pipe)
;连续命令执行符
$使用变量前导符
&任务管理,将命令变成后台任务
!
/目录分隔符
> 、>>数据流重定向:输出定向,>是替换,>>是累加
<、<<数据流重定向:输入定向
‘’单引号,不具有变量替换功能($为纯文本)
“”双引号,具有变量替换功能
``中间为可以先执行的命令,也可以使用$()
()中间为子shell的起始和结束
{}中间为命令区块的组合

10.5 数据流重定向

数据流重定向就是将数据给定向到其他地方去。

数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据,给它传输到其他地方去,如文件或打印机设备。

名称缩写代码传送所用的特殊字符
标准输入stdin0< 、 <<(<会覆盖已有的文件,而<<则追加)
标准输出stdout1> 、 >>
标准错误输出stderr22> 、 2>>
find /home -name .bashrc > list_right 2> list_error    将正确的输出输出到list_right,错误的输出到list_error  

find /home -name .bashrc  > list 2>&1   	不管错误还是正确,都输出到list文件中
find /home -name .bashrc &> list 			同上,不管错误还是正确,都输出到list文件中

<就是,将原本需要由键盘输入的数据,改由文件内容来替换。

[dj@study ~]$ cat > catfile		等键盘输入数据,并按Ctrl+d停止
testing
cat file test
[dj@study ~]$ cat catfile		显示这个得到的文件
testing
cat file test


现在将文件作为来源:
[dj@study ~]$ cat > catfile < ~/.bashrc
[dj@study ~]$ ll catfile ~/.bashrc
-rw-rw-r--. 1 dj dj 231 6月   6 19:12 catfile
-rw-r--r--. 1 dj dj 231 8月   8 2019 /home/dj/.bashrc



[dj@study ~]$ cat > catfile << "eof"	当输入eof的时候会自动终止输入
> This is a test just
> i donot know what to say
> eof
[dj@study ~]$ cat catfile 				查看catfile文件
This is a test just
i donot know what to say
[dj@study ~]$ echo "error message" 1>&2   				将正常的输出信息重定位到非正常中去,所以会输出
error message
[dj@study ~]$ echo "error message" 2> /dev/null 1>&2	将非正常输出的信息扔到垃圾桶中,将正常输出的信息重定位到非正常输出中去
[dj@study ~]$ cat /dev/null								仍旧nothing
[dj@study ~]$

10.5.2 命令执行的判断依据: ; && ||

前后命令无逻辑关系:用分号
前后命令有逻辑关系:用&&或者||

若前一个命令执行的结果为正确,在Linux下回返回一个$?=0的值。

这个&& 和|| 并非C++里的短路原则!!!

短路原则说的是:
a && b,如果 a为false,直接返回false;如果a为true,才进行b的检查,如果b为false,仍然返回false;
a || b,如果 a为true,直接返回true;如果a为false,才进行b的检查,只要b为true,仍然返回true;

而这里的 && 和||:
在含义上和C++语言中一致,但是在数值上,不一致!
a && b,如果a正确执行(返回0),才会执行b;如果a执行错误(返回非0),b命令不执行。
a || b,如果a正确执行(返回0),不会执行b;如果a执行错误(返回非0),b命令才会执行。

[dj@study ~]$ ls /tmp/test && touch /tmp/test/test.txt    如果这个目录存在,那么在其下创建文件;否则不创建文件
ls: 无法访问/tmp/test: 没有那个文件或目录


[dj@study ~]$ mkdir /tmp/test							创建了这个目录
[dj@study ~]$ ls /tmp/test && touch /tmp/test/test.txt	再次执行上面的命令,这时候就不报错了
[dj@study ~]$ ls /tmp/test								命令执行成功
test.txt


[dj@study ~]$ rm -r /tmp/test							先删除目录
[dj@study ~]$ ls /tmp/test || mkdir /tmp/test			判断目录是否存在,若不存在就创建
ls: 无法访问/tmp/test: 没有那个文件或目录					报错了,果然不存在
[dj@study ~]$ ll -d /tmp/test							但是,这时候也已经被新建好了
drwxrwxr-x. 2 dj dj 6 6月   6 19:53 /tmp/test


[dj@study ~]$ rm -r /tmp/test							
[dj@study ~]$ ls /tmp/test || mkdir /tmp/test && touch /tmp/test/abc.txt  
ls: 无法访问/tmp/test: 没有那个文件或目录
[dj@study ~]$ ll /tmp/test/abc.txt
-rw-rw-r--. 1 dj dj 0 6月   6 20:00 /tmp/test/abc.txt


command1  &&  command2  ||  command3   
如果command1执行成功,那么执行command2,command2肯定成功;那么不需执行command3
如果command1执行失败,那么不执行command2;前面执行失败了,去执行command3

10.6 管道命令

less、more、head、tail

(1)管道命令仅处理标准输出,对于标准错误会予以忽略;(通过 2>&1,使得2>变成1>,强行让标准错误可以被管道命令使用)
(2)管道命令必须要能够接受来自前一个命令的数据成为标准输入继续处理才行。

10.6.1 cut 和 grep

[dj@study ~]$ echo ${PATH}				
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/dj/.local/bin:/home/dj/bin
[dj@study ~]$ echo ${PATH} | cut -d ':' -f 5		以:为分隔符,从中选取第5段内容
/bin
[dj@study ~]$ echo ${PATH} | cut -d ':' -f 3,5		以:为分隔符,从中选取第3、5两段内容
/usr/bin:/bin


export | cut -c 12-20		这是将export输出的内容,截取每行12-20的字符
grep [-acinv] [--color=auto] '查找字符串' filename
		-a  将二进制文件以文本文件的方式查找数据
		-c  计算找到‘查找字符’的次数
		-i	忽略大小写,大小写视为相同
		-n	顺便输出行号
		-v	反向选择,显示出没有‘查找字符’内容的那一行
		--color=auto 可以将找到的关键字部分加上颜色的显示
显示全部登录信息:
[dj@study ~]$ last 
dj       pts/0        :0               Sat Jun  6 20:43   still logged in   
dj       :0           :0               Sat Jun  6 20:42   still logged in   
reboot   system boot  3.10.0-1062.el7. Sat Jun  6 20:41 - 20:56  (00:15)    
dj       pts/0        :0               Sat Jun  6 10:04 - 20:40  (10:36)    
dj       pts/0        :0               Sat Jun  6 09:19 - 10:04  (00:44)    
dj       :0           :0               Sat Jun  6 09:19 - down   (11:21)    
reboot   system boot  3.10.0-1062.el7. Sat Jun  6 09:17 - 20:40  (11:22)    
dj       pts/1        :1               Sun May 31 20:29 - 23:20  (02:50)    
dj       :1           :1               Sun May 31 20:26 - down   (02:54)    
root     pts/0        :0               Sun May 31 19:52 - 23:20  (03:28)    
root     :0           :0               Sun May 31 19:51 - down   (03:29)    
reboot   system boot  3.10.0-1062.el7. Sun May 31 19:49 - 23:21  (03:31)    
dj       pts/0        :0               Sun May 31 14:12 - 19:48  (05:35)    
dj       :0           :0               Sun May 31 14:11 - crash  (05:38)    
reboot   system boot  3.10.0-1062.el7. Sun May 31 14:10 - 23:21  (09:10)    
dj       pts/0        :0               Sat May 30 15:32 - 18:07  (02:34)    
dj       :0           :0               Sat May 30 15:23 - down   (02:44)    
reboot   system boot  3.10.0-1062.el7. Sat May 30 15:22 - 18:08  (02:45)    
dj       pts/0        :0               Sat May 30 11:22 - 15:22  (03:59)    
dj       :0           :0               Sat May 30 11:21 - crash  (04:00)    
reboot   system boot  3.10.0-1062.el7. Sat May 30 11:20 - 18:08  (06:47)    
dj       pts/0        :0               Tue May 26 15:30 - 09:10  (17:40)    
dj       :0           :0               Tue May 26 15:29 - 09:11  (17:41)    
reboot   system boot  3.10.0-1062.el7. Tue May 26 15:28 - 09:11  (17:42)    
dj       pts/0        :0               Mon May 25 17:21 - 19:20  (01:59)    
dj       :0           :0               Mon May 25 17:20 - 19:20  (02:00)    
reboot   system boot  3.10.0-1062.el7. Mon May 25 17:19 - 19:21  (02:01)    
dj       pts/0        :0               Thu May 14 17:08 - 22:11  (05:02)    
dj       :0           :0               Thu May 14 17:08 - crash (11+00:11)  
reboot   system boot  3.10.0-1062.el7. Thu May 14 17:07 - 19:21 (11+02:13)  
dj       pts/0        :0               Wed May 13 22:02 - 22:05  (00:02)    
dj       pts/0        :0               Wed May 13 21:39 - 22:00  (00:20)    
dj       pts/0        :0               Wed May 13 21:35 - 21:35  (00:00)    
dj       :0           :0               Wed May 13 21:31 - crash  (19:35)    
reboot   system boot  3.10.0-1062.el7. Wed May 13 21:30 - 19:21 (11+21:50)  
dj       tty2                          Tue May 12 21:43 - 22:11  (00:28)    
dj       pts/0        :0               Tue May 12 21:22 - 21:24  (00:02)    
dj       :0           :0               Tue May 12 21:15 - crash (1+00:15)   
reboot   system boot  3.10.0-1062.el7. Tue May 12 21:14 - 19:21 (12+22:06)  
dj       :0           :0               Tue May 12 20:30 - crash  (00:44)    
reboot   system boot  3.10.0-1062.el7. Tue May 12 20:29 - 19:21 (12+22:51)  
dj       pts/0        :0               Fri May  1 21:14 - 21:14  (00:00)    
dj       pts/0        :0               Wed Apr 29 21:46 - 08:02  (10:16)    
dj       :0           :0               Wed Apr 29 21:45 - down  (12+22:43)  
reboot   system boot  3.10.0-1062.el7. Wed Apr 29 21:43 - 20:28 (12+22:44)  
wtmp begins Wed Apr 29 21:43:52 2020



正向选择,只选包含root的:
[dj@study ~]$ last | grep 'root'
root     pts/0        :0               Sun May 31 19:52 - 23:20  (03:28)    
root     :0           :0               Sun May 31 19:51 - down   (03:29)   




反向选择,只选不含root的:
[dj@study ~]$ last | grep -v 'root'     
dj       pts/0        :0               Sat Jun  6 20:43   still logged in   
dj       :0           :0               Sat Jun  6 20:42   still logged in   
reboot   system boot  3.10.0-1062.el7. Sat Jun  6 20:41 - 20:56  (00:15)    
dj       pts/0        :0               Sat Jun  6 10:04 - 20:40  (10:36)    
dj       pts/0        :0               Sat Jun  6 09:19 - 10:04  (00:44)    
dj       :0           :0               Sat Jun  6 09:19 - down   (11:21)    
reboot   system boot  3.10.0-1062.el7. Sat Jun  6 09:17 - 20:40  (11:22)    
dj       pts/1        :1               Sun May 31 20:29 - 23:20  (02:50)    
dj       :1           :1               Sun May 31 20:26 - down   (02:54)    
reboot   system boot  3.10.0-1062.el7. Sun May 31 19:49 - 23:21  (03:31)    
dj       pts/0        :0               Sun May 31 14:12 - 19:48  (05:35)    
dj       :0           :0               Sun May 31 14:11 - crash  (05:38)    
reboot   system boot  3.10.0-1062.el7. Sun May 31 14:10 - 23:21  (09:10)    
dj       pts/0        :0               Sat May 30 15:32 - 18:07  (02:34)    
dj       :0           :0               Sat May 30 15:23 - down   (02:44)    
reboot   system boot  3.10.0-1062.el7. Sat May 30 15:22 - 18:08  (02:45)    
dj       pts/0        :0               Sat May 30 11:22 - 15:22  (03:59)    
dj       :0           :0               Sat May 30 11:21 - crash  (04:00)    
reboot   system boot  3.10.0-1062.el7. Sat May 30 11:20 - 18:08  (06:47)    
dj       pts/0        :0               Tue May 26 15:30 - 09:10  (17:40)    
dj       :0           :0               Tue May 26 15:29 - 09:11  (17:41)    
reboot   system boot  3.10.0-1062.el7. Tue May 26 15:28 - 09:11  (17:42)    
dj       pts/0        :0               Mon May 25 17:21 - 19:20  (01:59)    
dj       :0           :0               Mon May 25 17:20 - 19:20  (02:00)    
reboot   system boot  3.10.0-1062.el7. Mon May 25 17:19 - 19:21  (02:01)    
dj       pts/0        :0               Thu May 14 17:08 - 22:11  (05:02)    
dj       :0           :0               Thu May 14 17:08 - crash (11+00:11)  
reboot   system boot  3.10.0-1062.el7. Thu May 14 17:07 - 19:21 (11+02:13)  
dj       pts/0        :0               Wed May 13 22:02 - 22:05  (00:02)    
dj       pts/0        :0               Wed May 13 21:39 - 22:00  (00:20)    
dj       pts/0        :0               Wed May 13 21:35 - 21:35  (00:00)    
dj       :0           :0               Wed May 13 21:31 - crash  (19:35)    
reboot   system boot  3.10.0-1062.el7. Wed May 13 21:30 - 19:21 (11+21:50)  
dj       tty2                          Tue May 12 21:43 - 22:11  (00:28)    
dj       pts/0        :0               Tue May 12 21:22 - 21:24  (00:02)    
dj       :0           :0               Tue May 12 21:15 - crash (1+00:15)   
reboot   system boot  3.10.0-1062.el7. Tue May 12 21:14 - 19:21 (12+22:06)  
dj       :0           :0               Tue May 12 20:30 - crash  (00:44)    
reboot   system boot  3.10.0-1062.el7. Tue May 12 20:29 - 19:21 (12+22:51)  
dj       pts/0        :0               Fri May  1 21:14 - 21:14  (00:00)    
dj       pts/0        :0               Wed Apr 29 21:46 - 08:02  (10:16)    
dj       :0           :0               Wed Apr 29 21:45 - down  (12+22:43)  
reboot   system boot  3.10.0-1062.el7. Wed Apr 29 21:43 - 20:28 (12+22:44)  
wtmp begins Wed Apr 29 21:43:52 2020


将root用户的登录信息那一行拿到,用cut取出第一列数据:
[dj@study ~]$ last | grep 'root' | cut -d ' ' -f 1
root
root
[dj@study ~]$ last | grep 'root' | cut -d ' ' -f1	这里的参数-f与数字1中间可以无空格
root
root


读取/etc/man_db.conf文件,找到包含 'MANPATH' 的那些行,并将关键字'MANPATH' 高亮显示:
grep --color=auto 'MANPATH' /etc/man_db.conf
grep 'MANPATH' /etc/man_db.conf					同上

10.6.2 排序命令:sort、wc、uniq

[dj@study ~]$ cat /etc/passwd | sort
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...


以第三栏来排序:
[dj@study ~]$ cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
dj:x:1000:1000:dj:/home/dj:/bin/bash
...

以数字顺序排序:
[dj@study ~]$ cat /etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...


显示最近登录的用户名,并按照用户名顺序排序
[dj@study ~]$ last | cut -d ' ' -f1 | sort
dj
dj
...
uniq [-ic]
		-i  忽略大小写字符的不同
		-c	进行计数



last | cut -d ' ' -f1 | sort |uniq    排序后,将重复的内容只显示一个:
输出:
dj
reboot
root
wtmp



last | cut -d ' ' -f1 | sort |uniq -c 排序后,将重复的内容只显示一个,且统计每个出现的总次数
输出:
     30 dj
     13 reboot
      2 root
      1 wtmp
wc [-lwm]
	 -l  仅列出行
	 -w  仅列出多少字(英文字母)
	 -m	 多少字符
	 
	 
cat /etc/man_db.conf | wc	统计该文件中有多少内容
输出:
131     723    5171			行、字数、字符数


一行命令取得登录系统的总人次,将那些不对的内容过滤掉,统计对的行数即可:
last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' | grep -v 'unknown' | wc -l
输出:
32


查看当前账号文件中有多少个账号:
cat /etc/passwd | wc -l

10.6.3 双向重定向:tee

tee可以让标准输出转存一份到文件,并将同样的数据继续输送到屏幕上去处理。

tee [-a] filename
		-a  以累加方式将数据添加进filename,而非覆盖


last | tee last.list | cut -d " " -f1		将last的信息同时保存一份到last.list文件了
last | cut -d " " -f1 | tee last.list		将cut处理后的内容保存一份到last.list

10.6.4 字符转换命令:tr、col、join、paste、expand

tr [-ds] SET1 ...
	  -d  删除信息中的SET1这个字符
	  -s  替换掉重复的字符


last | tr '[a-z]' '[A-Z]'  将last中的小写字符都换成大写字符
last | tr [a-z] [A-Z]	   同上


cat /etc/passwd | tr -d ':'   删除每行的冒号
col [-xb]
	-x  将tab键转换成对等的空格键

cat -A /etc/man_db.conf							显示tab键^I

cat /etc/man_db.conf | col -x | cat -A | more	替换为空格键并显示
join [-ti11] [-ti12] file1 file2			使用之前应该先排序
		-t	默认以空格字符分隔数据,并且比对第一个栏位的数据,如果相同,就合并
		-i  忽略大小写
		-1	这个是数字的1,第一个文件要用哪个栏位来分析
		-2	同上

join -t ':' /etc/passwd /etc/shadow | head -n 3	    将前3行以:为分隔符的两各文件合并
join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3	文件1以第4栏,文件2以第3栏比较
paste [-d] file1 file2
		-d  后面可以接分隔符,默认分隔符是tab键
		-	如果file部分写成-,表示来自标准输入的数据

paste /etc/passwd /etc/shadow
cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3  将3个文件粘贴到一起,只看前三行
expand [-t] filename 		自动将Tab键转换成空格键
		-t  接数字,让一个tab键代表多少个字符,默认是8个字符

grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 8 -| cat -A

10.6.5 划分命令:split

split [-bl] file PREFIX
		-b  后接欲划分成的文件大小,可加单位,b,k,m等
		-l  以行数来划分
		PREFIX 前缀字符



split -b 300k /etc/services services
ll -k services*
输出:
-rw-r--r--. 1 root root 307200 6月   6 22:25 servicesaa
-rw-r--r--. 1 root root 307200 6月   6 22:25 servicesab
-rw-r--r--. 1 root root  55893 6月   6 22:25 servicesac


cat servicesa* >> servicesback
ll -k services*
输出:
-rw-r--r--. 1 root root 307200 6月   6 22:25 servicesaa
-rw-r--r--. 1 root root 307200 6月   6 22:25 servicesab
-rw-r--r--. 1 root root  55893 6月   6 22:25 servicesac
-rw-r--r--. 1 root root 670293 6月   6 22:26 servicesback


ls -al / | split -l 10 - lsroot
wc -l lsroot*
输出:
  10 lsrootaa
  10 lsrootab
   4 lsrootac
  24 总用量

10.6.6 参数代换:xargs

[dj@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
uid=0(root) gid=0(root)=0(root)
uid=1(bin) gid=1(bin)=1(bin)
uid=2(daemon) gid=2(daemon)=2(daemon)


加上-p会询问是否进行id操作:
[dj@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
id root ?...y
uid=0(root) gid=0(root)=0(root)
id bin ?...y
uid=1(bin) gid=1(bin)=1(bin)
id daemon ?...y
uid=2(daemon) gid=2(daemon)=2(daemon)


如果分析到'sync'就停止操作,-e与'sync'中间没有空格:
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -e'sync' -n 1 id

很多命令不支持管道命令,可以通过xargs来提供该命令使用标准输入。

找出/usr/sbin中具有特殊权限的文件名:
find /usr/sbin -perm /7000 | xargs ls -l
ls -l $(find /usr/sbin -perm /7000)

10.6.7 关于减号-的用途

tar -cvf - /home | tar -xvf - -C /tmp/homeback
这里解释如下:
先把/home下的数据打包到标准输出(-)
再把该标准输出(-)通过管道(|)传输到后面,作为解压缩的标准输入(-)
可以省略文件名
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值