Linux - Bash (Basic)

1 Basic Startup

1.1 Bash - Bourne Again shell

第一个重要的shell是Bourne shell,他在1979年Unix version7中加入,即sh,很多UNIX的应用的管理仍然依赖它。第一个广泛使用的其他shell是几年后C shell,因为他和C编程有些相似。还有就是Korh shell,他集合了前面两者的优点并加上自己的特点,但是虽然下载是免费的,作为一个商业的shell,他在某些场合使用时需要付费的。而bash,即Bourne Again shell是免费,他提出一个发布的方式,copyleft,有FSF(Free Software Foundation)的Brain Fox提供的,后来又Chet Ramey维护和发布新的版本,在GNU(GNU’s Not Unix)中使用。他取缔了所有和商业性质与有关的UNIX部分。

wiki是这样描述bash:
bash 是一个为GNU 项目编写的Unix shell 。它的名字是一系列缩写:Bourne-Again SHell — 这是关于Bourne shell(sh)的一个双关语(Bourne again / born again)。Bourne shell是一个早期的重要shell,由Stephen Bourne在1978年前后编写,并同Version 7 Unix一起发布。bash则在1987年由Brian Fox创造。在1990年,Chet Ramey成为了主要的维护者。bash是大多数Linux 系统以及Mac OS X v10.4 默认的shell,它能运行于大多数Unix风格 的操作系统之上,甚至被移植到了Microsoft Windows 上的Cygwin 和MSYS 系统中,以实现windows的POSIX 虚拟接口。在现在的desktop Linux中,都是bash,倒是少了我们去设定bash的方式。Linux都支持sh,如果可以在命令行中敲入sh,尽可以进入sh模式。不过我们有bash,没必要进去sh。在login后,可以通过Ctrl-D来进行logout,这种方式我好像没有用过,不过使用exit或者logout一样可以达到目的,就没比较记下这么多的快捷键。

bash中的间隔符合可以是空格或者tab。

1.2 Env Bash Check

RS:Record Separator,记录分隔符
ORS:Output Record Separate,输出当前记录分隔符
FS:Field Separator,字段分隔符
OFS:Out of Field Separator,输出字段分隔符

echo $BASH
echo $BASH_VERSION

1.3 IFS 变量

Shell 脚本中有个变量叫 IFS(Internal Field Seprator) ,内部域分隔符。完整定义是The shell uses the value stored in IFS, which is the space, tab, and newline characters by default, to delimit words for the read and set commands, when parsing output from command substitution, and when performing variable substitution.
Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,

set 是显示设置shell变量,仅在本 shell 中有效;
env 是显示设置用户环境变量 ,仅在当前会话中有效。

换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。

1.4 查看变量 IFS 的值

直接输出IFS是看不到的,把它转化为二进制就可以看到了,"040"是空格,“011"是Tab,“072” 表示冒号, “012"是换行符”\n” 。最后一个 012 是因为 echo 默认是会换行的。

$ echo $IFS                      # output nothing
$ echo "$IFS" | od –b            # need to use quote
$ IFS=:;

$ set x y z
$ echo $*    # x y z
$ echo “$*”  # x:y:z
$ echo $@    # x y z
$ echo “$@”  # x y z
  • 重新定义IFS,使用分号引用时,会使用重新定义的值组合字符串,否则使用默认的分隔符组合。
  • $* 会根据 IFS 的不同来组合值,而 $@ 则会将值用" "来组合值
  • 这个地方要注意下!!如果IFS就是空格,那么类似于" [space][space]a[space]b[space][space]c "会合并重复的部分,且去头空格,去尾空格,那么最终输出会变成类似 a[space]b[space]c ,所以,如果IFS是默认值,那么处理的结果就很好算出来,直接合并、忽略多余空格即可!
  • 慎改IFS!!!

1.5 批量输出

usage() {
	cat << -EOF-
	Usage:
	$0 -I interface -i ipaddr
-EOF-
	exit 1
}

2 基本I/O操作、特殊字符、控制键和帮助

2.1 I/O操作

几个常用的命令包括:

  • cat(copy输入到输出)
  • grep(在输入中查询某些字符串), 常用的option:-v, -i, -n
  • sort(排序)从用option:-nr 按数字排序
  • uniq , uniq -c 在每列行统计出现次数
  • tee(输出)
  • cut(抽取列)
  • awk (文本处理)
  • sed(在输入中提供edit)
  • tr(将输入中的某些字符更换为另外的字符)
  • paste 合并文件
  • strace 跟踪进程中的系统调用
  • pstack 跟踪进程栈
  • lsof 一切皆文件
  • objdump 二进制文件分析
  • nm 目标文件格式分析
  • ldd 查看引用的库文件
  • vmstat 监视内存使用情况
  • tcpdump 抓包工具
  • split命令
    -l 指定行数,每个文件多少行
    -b 指定大小,每个文件100M.,这种担心会破坏一行的完整性
    -d 指定用数字递增为生成的文件名编号 test111为前缀
    -a 指定有几位数字 这里指定了4位,则从0000开始
  • find 查找文件和目录
  • kill
  • pwdx 查看进程的工作目录
示例:
- find
语句写法:find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \;
- paste
奇偶行合并:paste n48.csv n58.csv |tr "\t" "\n"
逗号合并:paste -d ',' file1 file2 | tee file3
- cut
将/etc/passwd中抽取用户名,并按排序显示出来。
命令为:cut -d: -f1 /etc/passwd | sort | lp
表示列是按“:”来分隔,我们需要第一列,-d:之间可以加空格。
- sed
打印第3行:sed -n '3p' /var/log/yum.log
打印39行:sed -n '3,9p' /var/log/yum.log
打印包含pattern1到pattern2的行:sed -n '/pattern1/,/pattern2/p' yum.log
行内文字替换:sed -i 's/root/world/g' yum.log #直接文件内替换
行后增加新内容:sed '1,4i hahaha' yum.log
- awk
awk -F ',' '{print $3}' file | awk '{sum+=$1} END {print sum}' |awk -v ct=$client '{print $1/ct}'
输出第三列求和,赋值awk变量ct,计算平均
- sort & uniq
netstat -ant|awk '{print $4 "," $6}'| sort | uniq -c |sort -nr  | head -n 10
- kill
$kill -l
1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL
5) SIGTRAP  6) SIGABRT  7) SIGBUS   8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR  31) SIGSYS  34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

参考:https://linuxtools-rst.readthedocs.io/zh_CN/latest/index.html

2.2 文件类型

-b FILE
FILE exists and is block special

-c FILE
FILE exists and is character special

-d FILE
FILE exists and is a directory

-e FILE
FILE exists

-f FILE
FILE exists and is a regular file

-g FILE
FILE exists and is set-group-ID

-G FILE
FILE exists and is owned by the effective group ID

-h FILE
FILE exists and is a symbolic link (same as -L)

-k FILE
FILE exists and has its sticky bit set

-L FILE
FILE exists and is a symbolic link (same as -h)

-O FILE
FILE exists and is owned by the effective user ID

-p FILE
FILE exists and is a named pipe

-r FILE
FILE exists and read permission is granted

-s FILE
FILE exists and has a size greater than zero

-S FILE
FILE exists and is a socket

-t FD file descriptor FD is opened on a terminal

-u FILE
FILE exists and its set-user-ID bit is set

-w FILE
FILE exists and write permission is granted

-x FILE
FILE exists and execute (or search) permission is granted

2.3 前台和后台命令

• 命令后台运行,即在运行结束之前,可以在当前的terminal执行其他操作,使用&
• 在系统启动后运行的rc.local文件中加入我们的服务命令:myservice &,这样在系统启动后myservice就作为后台作业一直运行
• Nice命令来设置优先级, 可以通过man nice来查阅。在cgywin中缺省优先级别为10,数值越大优先级别越低,nice -n8 command1,将command1的优先基本设置为8

keyBehavior
stty -a查看默认命令
CTRL-C放弃整行,不执行
CTRL-D停止input,通常logout
CTRL-/在CRTL-C无效的使用,用于停止当前命令,其实使用kill也可以,没必要记太多
CTRL-S停止屏幕输出
CTRL-Q重新输出屏幕
CTRL-U删除正航命令,一般CTRL-C效果一样
CTRL-Z挂起当前命令,在这本书的第8章详细描述
CTRL-J等同于RETURN,即回车,在ASCII中为LINEFEED,UNIX中允许用之来替代RETURN
CTRL-L清屏
CTRL-M回车
CTRL-O等同于RETURN,然后显示在history中下一条命令
CTRL-T将两个字符交换位置
CTRL-U删除开始到光标所在处
CTRL-V加入quote,但是我在cgywin中无效
CTRL-[等同于Esc
ESC-C将字母变为大写,并光标移到下一个word处
ESC-U将word的位于光标即后面的字母变为大写,并光标移到下一个word处
ESC-L将word的位于光标即后面的字母变为小写,并光标移到下一个word处
ESC-.将上一命令的最后的word加入光标所在处
ESC-_同ESC-.

3 特殊文件、别名、选项和参数

3.1 source .bash_profile

Linux一般都是使用.bash_profile,如果没有系统会去找.bash_login,次去找.profile。另外还有.bashrc文件,这是在调用subbash的时候系统执行的,也即是我们敲入bash 来开启新的bash环境,这在实际中是很少用的。.bash_logout顾名思义,是在logout是调用。

3.2 alias : alias name =command

请注意在“=”的前后是不允许留有空格的
alias:例如当前alias的的列表
alias name :例如给name的真正含义
unalias name :取消该name的别名捆绑

3.3 选项

通过set –o optionname 来打开某个环境选项,用set +o optionname 来关闭它,注意是-表示on,+表示off,这是应为-比较容易按,而+需要按两个键。可以用set -o来查看当前环境的开关情况,例如为了禁止CTRL-D引发logout,我们可以打开ignoreeof,及set –o ignoreeof。我觉得有很多这样的环境设定参数,但是其实很少使用,需要的时候可以通过man set来确定一下就可以。另外可能比较常用的是noclobber,禁止通过>的重定向方式重写一个已有的文件。在bash 2.0,提供shopt来设置,也提供了一些来设置和unset的方式,但是我不认为需要去记忆这些,在实际应用上是很少使用的。这里就不记录。

3.4 参数设定

相对环境的设定,参数的设定更有有意思,set或者shopt是实际上很少使用的,而用户的环境变量设定,例如Java是lib或者bin的指定是通过.bash_profile来设定的。参数设置也就是varname =value ,通常varname都是大写,例如JAVADIR,我们查看一个varname,常用的方式就是echo,例如我们已经设定了TT=’test for it’,可以通过echo T T 或者 e c h o “ TT或者echo “ TT或者echoTT”来查看。如果没有,就给出空行。

3.4.1 单引号和双引号

我们来看看下面的例子:varname=alice;echo "$varname"和echo $varname,都显示alice,而echo ‘$varname’则显示$varname,这说明在双引号下是解析参数的,而单引号则表示一串字符不解析里面的内容。在看一个例子varname=’four space here’,如果echo “$varname”,则显示four space here,如果echo $varname,等同于echo four space here,显示four space here。双引号内,表示一个整体,作为一个word出现,如果我们echo "four space here"也一样在here之前有多个空格。
  在参数设定中分清单引号和双引号是必须的。

3.4.2 内置参数

Linux系统包含一些内置参数,我们可以通过修改这些参数来改变配置。在我们自定义的参数名中要避免与之重名。
下面是history相关的部分参数:

  • HISTCMD记录单前是第N个命令,可以echo来查看一下
  • HISTFILESIZE表示记录在文件中历史命令的数目,也即文件的最大行数
  • HISTSIZE表示记录在内存中最大的历史命令的数目
  • HISTIGNORE:表示不记录某些命令,例如HISTIGNORE=l*:&,表示不记录l开头的命令,以及不记录重复的命令(&表示重复命令)
  • HISTTIMEFORMAT:如果为null,则不显示时间,我们可以为之设定时间格式,例如HISTTIMEFORMAT=”%y/%m/%d %T “,请注意这里使用的是双引号

3.4.3 时间格式(man date)

Command: date +[format]

$ date  +"%Y-%m-%d %H:%M:%S"
2019-08-15 23:08:23
$ date -d @1564567787
Wed Jul 31 18:09:47 CST 2019

Format Replaced by

formatcomments
%aThe locale’s abbreviated weekday name
%AThe locale’s full weekday name
%bThe locale’s abbreviated month name
%BThe locale’s full month name
%cThe locale’s appropriate date and time representation
%CThe century number (the year divided by 100 and truncated to an integer) as a decimal number [00-99]
%dThe day of the month as a decimal number [01-31]
%DThe date in American format; the same value as %m/%d/%y.
%eThe day of the month as a decimal number [1-31]; a single digit is preceded by a space
%hThe same as %b
%HThe hour (24-hour clock) as a decimal number [00-23]
%IThe hour (12-hour clock) as a decimal number [01-12]
%jThe day of the year as a decimal number [001-366]
%mThe month as a decimal number [01-12]
%MThe minute as a decimal number [00-59]
%nA newline character
%pThe locale’s equivalent of either a.m. or p.m
%rThe time in a.m. and p.m. notation; in the POSIX locale this is equivalent to %I:%M:%S %p - 09:08:20 PM
%RThe time in 24-hour notation (%H:%M)
%SThe second as a decimal number [00-60]
%tA tab character
%TThe time (%H:%M:%S) - 21:08:40
%uThe weekday as a decimal number [1-7], with 1 representing Monday
%UThe week number of the year (Sunday as the first day of the week) as a decimal number [00-53]
%VThe week number of the year (Monday as the first day of the week) as a decimal number [01-53]; if the week containing 1 January has four or more days in the new year, then it is considered week 1—otherwise, it is the last week of the previous year, and the next week is week 1
%wThe weekday as a decimal number [0-6], with 0 representing Sunday
%WThe week number of the year (Monday as the first day of the week) as a decimal number [00-53]; all days in a new year preceding the first Monday are considered to be in week 0
%xThe locale’s appropriate date representation
%XThe locale’s appropriate time representation
%yThe year without century as a decimal number [00-99]
%YThe year with century as a decimal number
%ZThe timezone name or abbreviation, or by nothing if no timezone information exists
%%%

3.4.4 提示符

在linux中,提示符通常为KaTeX parse error: Expected 'EOF', got '#' at position 11: ,已经root用户的#̲,这个和具体的linux版本有…的方式,可以重新设置PS1,即PS1="/u " ,如果我们还希望加上时间,设为 P S 1 = " / u − / A ",如果我们还希望加上时间,设为PS1="/u-/A ",如果我们还希望加上时间,设为PS1="/u/A "。
PS2是命令尚未输完,第二上的换行继续的提示符,通常为>。例如我们上面介绍的分段方式。PS3和PS4用于编程和debug。在以后的章节中介绍。下表为提示符的设置内容
Eg :

\[\e[37;0m\]######[\[\e[31;1m\]\d \A \[\e[33;1m\]\u@\[\e[33;1m\]10.244.102.207:\[\e[36;1m\]\w\[\e[37;0m\]]#####\n$  
 ######[Tue Jan 17 08:00 c4dev@10.244.102.207:~]#####
CommandMeaning
/aThe ASCII bell character (007)
/AThe current time in 24-hour HH:MM format
/dThe date in “Weekday Month Day” format
/D{format} The format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation; the braces are required
/eThe ASCII escape character (033)
/HThe hostname
/hThe hostname up to the first “.”
/jThe number of jobs currently managed by the shell
/lThe basename of the shell’s terminal device name
/nA carriage return and line feed
/rA carriage return
/sThe name of the shell
/TThe current time in 12-hour HH:MM:SS format
/tThe current time in HH:MM:SS format
/@The current time in 12-hour a.m./p.m. format
/uThe username of the current user
/vThe version of bash (e.g., 2.00)
/VThe release of bash ; the version and patchlevel (e.g., 2.00.0)
/wThe current working directory
/WThe basename of the current working directory
/#The command number of the current command
/!The history number of the current command
/$If the effective UID is 0, print a #, otherwise print a $
/nnnCharacter code in octal
//Print a backslash
/[Begin a sequence of non-printing characters, such as terminal control sequences
/]End a sequence of non-printing characters

3.4.5 命令查找路径

PATH存储命令查找文件,可以用echo $PATH来查看。命令都是执行文件,它所在的目录如果不在PATH内,在执行的时候必须指出文件所在目录。PATH里面可包含多个文件目录,之间用“:”来分割,例如/bin:/usr/bin:/usr/local/bin:/usr/X386/bin 。它们是由先后顺序的,我们敲入一个命令,将按顺序进行查找,直至找到。
  有一些命令是已经编译在Linux中的,例如cd,echo,这些命令不是通过文件执行的命令。我们有时需要增加这些路径,例如我们将一些执行文件放入~/bin中,我们希望登录的时候能够直接运行,而不需要指出路径。我们在.bash_profile文件的最后加入PATH=$PATH:/home/wei/bin ,请注意这里的顺序,为了避免我们自己目录下的命令干扰系统命令(同时也可能引起系统安全隐患),我们一般都将新增的路径放置最后。如果发生冲突,而我们希望使用放置在后面目录的命令,在执行是需要执行路径,例如在~/bin/more,这个命令和系统命令冲突,在执行时使用$~/bin/more 。

3.4.6 命令hashing

为了提高在PATH路径中查询命令的速度,Linux采用了命令hashing的方式。当shell在PATH中找到一个命令时,将这个命令放入哈希表。当再次使用命令时,将先在哈希表中进行查询,可以用hash 命令来查看当前的哈希表,里面不仅包括命令的完整路径,还包括在本次login中使用的次数。可以用hash -r 来清除整个哈希表,用-d 来删除某个命令,用-p 来加入某个命令(即使这个命令不存在)。在环境中可以通过hashall 的set来设置on或者off,但是我们没有必要去修改它。

3.4.7 目录查询路径

在cd命令的使用,如果非绝对路径,会在当前路径开始查询,可以设置CDPATH来制定cd命令的查询路径。格式和PATH类似,使用“:”作为分割,并具有前后先后顺序。例如我们设置CDPATH=:~/mybook ,注意不允许路径以”/”开头,也不允许以”./“”…/“开头。在上面例子中,我们敲入cd doc,现在当前目录查找,如果没有则接着在~/mybook下查找doc目录。一般来讲,如果有一个目录我们清楚去,我们通常将这个目录设置为某个变量,例如 mydir=~/myproject/mylearning/,然后通过cd mydir来进入,而不采用CDPATH的方式。

3.4.8 其他参数

除了前面介绍的参数外,还有很多其他的参数,下面一些比较常见。

  • HOME :用户home目录
  • SECONDS :shell被invoke的时间间隔
  • BASH :当前使用的bash的路径
  • BASH_VERSION :shell的版本,例如我使用的cygwin的版本是3.2.49(22)-release
  • BASH_VERSINFO :当前使用shell的主版本信息。例如我的版本是3
  • PWD :当前路径
  • OLDPWD :上次cd前的路径
    这几个参数用于获取数值,没有案例用于设置。

3.5 文件的修订

当我们修改.bash_profile,.bashrc当然可以使用vi等editor的方式,但是我们也可以简单实用echo,将所需要的设置附加在文件的最后,例如我们要设置PS1="/u /!—> “,我们需要将其加在.bash_profile的最后,使用
$ echo 'PS1=”/u /!–> " ’ >> ~/.bash_profile
注意这里使用了单引号,这是为了避免里面有$或者”或者其他所带来的意义的变化。>>表示附加在文件的最后,而>表示则覆盖整个文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值