shell知识点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell知识点相关的知识,希望对你有一定的参考价值。
参考技术A 一些经典的 Shell 脚本面试问题 - CSDN博客1. 如何在脚本中使用参数 ?
第一个参数 : $1,第二个参数 :$2
例子 : 脚本会复制文件(arg1) 到目标地址(arg2)
./copy.sh file1.txt /tmp/
cat copy.sh
#!/bin/bash
cp $1 $2
2. 如何计算传递进来的参数 ?
$#
3. 如何检查之前的命令是否运行成功?
$?
4. 如何获取文件的最后一行 ?
tail -1
5. 如何获取文件的第一行 ?
head -1
6. 如何获取一个文件每一行的第三个元素 ?
awk'print $3'
7. 假如文件中每行第一个元素是FIND,如何获取第二个元素
awk' if ($1 == "FIND") print$2'
8. 如何调试 bash 脚本
将 -xv 参数加到#!/bin/bash 后
例子:
#!/bin/bash –xv
9. 举例如何写一个函数 ?
function example
echo "Hello world!"
10. 如何向连接两个字符串 ?
V1="Hello"
V2="World"
V3=$V1$V2
echo $V3
输出
HelloWorld
11. 如何进行两个整数相加 ?
V1=1
V2=2
let V3=$V1+$V2
echo $V3
输出
3
12. 如何检查文件系统中是否存在某个文件 ?
if [ -f /var/log/messages ]
then
echo "File exists"
fi
13. 写出 shell 脚本中所有循环语法 ?
for 循环 :
foriin$(ls);do
echo item:$i
done
while 循环 :
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done
until 循环 :
#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]; do
echo COUNTER $COUNTER
let COUNTER-=1
done
14. 每个脚本开始的#!/bin/sh 或 #!/bin/bash 表示什么意思?
这一行说明要使用的 shell。#!/bin/bash表示脚本使用 /bin/bash。对于 python 脚本,就是 #!/usr/bin/python。
15. 如何获取文本文件的第 10 行 ?
head -10 file|tail -1
16. bash 脚本文件的第一个符号是什么
#
17. 命令:[ -z"" ] && echo 0 || echo 1 的输出是什么
0
18. 如何在后台运行脚本 ?
nohup command&
19. "chmod 500 script" 做什么 ?
使脚本所有者拥有可执行权限。
20. ">" 做什么 ?
重定向输出流到文件或另一个流。
21. & 和&& 有什么区别
& - 希望脚本在后台运行的时候使用它
&& - 当前一个脚本成功完成才执行后面的命令/脚本的时候使用它
22. bash shell 脚本中哪个符号用于注释 ?
#
23. ' 和 " 引号有什么区别 ?
' - 当我们不希望把变量转换为值的时候使用它。
" - 会计算所有变量的值并用值代替。
24. 如何在脚本文件中重定向标准输出和标准错误流到log.txt 文件 ?
在脚本文件中添加 "exec >log.txt2>&1" 命令。
25. 如何只用 echo 命令获取字符串变量的一部分 ?
echo $variable:x:y
x - 起始位置
y - 长度
例子:
variable="My name is Petras, and I amdeveloper."
echo $variable:11:6 # 会显示 Petras
26. 如何使用 awk 列出 UID 小于 100 的用户 ?
awk -F: '$3<100' /etc/passwd
27. 写程序为用户计算主组数目并显示次数和组名
cat /etc/passwd|cut -d: -f4|sort|uniq-c|while read c g
do
echo $c; grep :$g: /etc/group|cut -d:-f1;|xargs -n 2
done
28. 如何获取变量长度 ?
$#variable
29. 如何打印变量的最后 5 个字符 ?
echo $variable: -5
30. 如何只用 echo 命令替换字符串的一部分 ?
echo $variable//pattern/replacement
31. 如何计算本地用户数目 ?
wc -l /etc/passwd|cut -d" " -f1 或者 cat /etc/passwd|wc -l
32. 不用 wc 命令如何计算字符串中的单词数目 ?
set $string
echo $#
33. 如何列出第二个字母是 a 或 b 的文件 ?
ls -d ?[ab]*
34. 如何将整数 a 加到 b 并赋值给 c ?
c=$((a+b))
或
c=`expr $a + $b`
或
c=`echo "$a+$b"|bc`
35. 如何去除字符串中的所有空格 ?
echo $string|tr -d " "
36. 写出输出数字 0 到 100 中 3 的倍数(0 3 6 9…)的命令 ?
for i in 0..100..3; do echo $i; done
或
for (( i=0; i<=100; i=i+3 )); do echo"Welcome $i times"; done
37. 如何打印传递给脚本的所有参数?
echo $*
或
echo $@
38. [ $a == $b ] 和[ $a -eq $b ] 有什么区别
[ $a == $b ] - 用于字符串比较
[ $a -eq $b ] - 用于数字比较
39. = 和 == 有什么区别
= - 用于为变量赋值
== - 用于字符串比较
40. 写出测试 $a 是否大于 12 的命令 ?
[ $a -gt 12 ]
41. 如何检查字符串是否以字母"abc" 开头 ?
[[ $string == abc* ]]
42. [[ $string == abc* ]] 和 [[ $string == "abc*" ]] 有什么区别
[[ $string == abc* ]] - 检查字符串是否以字母 abc 开头
[[ $string == "abc" ]] - 检查字符串是否完全等于 abc
43. 如何列出以 ab 或 xy 开头的用户名 ?
egrep "^ab|^xy" /etc/passwd|cut-d: -f1
44. bash 中 $! 表示什么意思 ?
后台最近执行命令的 PID.
45. $? 表示什么意思 ?
前台最近命令的结束状态。
46. 如何输出当前 shell 的 PID ?
echo $$
47. $* 和 $@ 有什么区别*
$* - 以一个字符串形式输出所有传递到脚本的参数
$@ - 以 $IFS 为分隔符列出所有传递到脚本中的参数
48. 如何在 bash 中定义数组 ?
array=("Hi" "my""name" "is")
49. 如何打印数组的第一个元素 ?
echo $array[0]
50. 如何打印数组的所有元素 ?
echo $array[@]
51. 如何输出所有数组索引 ?
echo $!array[@]
52. shell 脚本如何获取输入的值 ?
a) 通过参数
./script param1 param2
b) 通过 read 命令
read -p "Destination backup Server :" desthost
Linux 基础知识 | shell知识
Linux 基础知识 | shell知识
在Linux
操作系统,需要使用shell
程序将下达的指令去沟通内核(kernel
),以便Kernel
控制计算机硬件进行工作。其中shell
程序发展者众,而Linux
中默认的shell
是bash
程序。本篇主要介绍bash
的相关功能以及使用方式。
系统可用的shell
可以通过以下方式查看系统中可用的shell
程序
[root@VM_16_15_centos ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
可以通过查看/etc/passwd
查看每个用户登录后使用的默认shell
程序:
[root@VM_16_15_centos ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...省略...
从上面的信息来看,默认情况下,root
用户登录后使用的shell
程序为/bin/bash
,这个shell
是本篇文章的主要内容。
Bash shell的主要优点
- 命令记忆功能:
bash
会把上一次登录所执行过的指令都记录在~/.bash_history
中,可以在命令行中按上下键
就可以找到前一个或者后一个的指令了。 - 命令补全功能:在某些时候我们只记得了某个命令或者文件的部分描述,比如开头几个单词,这个时候就可以使用命令补全功能了,通过按
[tab]
键即可自动列出所有可用的指令或者文件路径。 - 命令别名功能,可以通过设置某个命令加参数为一个别名,然后可以通过别名执行该命令,例如一般情况下系统都会把
ls -l
设置一个ll
的别名,这个时候我们只需要输入ll
则可以达到ls -l
的效果了。
命令别名
查看别名
[root@VM_16_15_centos ~]# alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
设置别名:
alias ll='ls -l'
取消别名
unalias ll
历史命令
查看历史命令:
history
执行上一条指令:
!!
执行history
列表中的序号为937的指令
!937
执行最近一个以ca
开头的指令
!ca
指令的搜寻顺序
当一个指令被下达的时候,会按照如下顺序寻找该指令:
- 以绝对路径或相对路径执行,例如
/bin/ls
- 由
alias
找到指令执行 - 由
bash
内置指令执行 - 通过PATH变量顺序搜索到第一个指令执行
Bash shell环境变量
在登录进入Linux
系统的时候,bash
会读取一些配置文件,这些配置文件各自的作用都不一样,通常情况下,我们在安装一些软件的时候,要把某些路径加入环境变量,便于更方便的执行这些命令。
/etc/profile
系统整体的配置,一般情况下不需要修改这个文件~/.bash_profile
或者~/.bash_login
或~/.profile
是属于使用者个人设置。一般情况下,用户会修改这里的环境变量。
/etc/profile
文件可以利用使用者的uid来设定一些变量,可以通过查看这个文件内容:
[root@VM_16_15_centos ~]# cat /etc/profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.
pathmunge ()
case ":$PATH:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
if [ -x /usr/bin/id ]; then
if [ -z "$EUID" ]; then
# ksh workaround
EUID=`/usr/bin/id -u`
UID=`/usr/bin/id -ru`
fi
USER="`/usr/bin/id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
if [ "$-#*i" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
unset i
unset -f pathmunge
这个文件设置的变量主要有:
PATH
会根据uid
决定PATH
变量是否包含sbin
目录的命令MAIL
根据账号设置mailbox
到/var/spool/mail/
账号名USER
设置账号变量HOSTNAME
设置主机名变量HISTSIZE
历史命令记录数量unmask
一般用户
除了导入以上环境变量外,还会读取/etc/profile.d/*.sh
去执行相关的shell script
文件,这里面的shell scripts
文件主要作用是规范了bash
窗口的颜色、语系、ll
别名、vi
别名、which
别名等相关操作。
而~/.bash_profile
或者~/.bash_login
或~/.profile文件则会在读完/etc/profile之后读取,这几个文件会按照顺序读取,如果读到了第一个文件,后面的文件就不会读取了(一般情况下都是
.bash_profile`文件)
我们来查看下这个文件的内容:
[root@VM_16_15_centos ~]# 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/bin
从输出的信息看,这个文件主要是在PATH变量中加入了~/bin
目录,并且读取了~/.bashrc
文件。
所以如果需要添加环境变量,则可以修改~/.bash_profile
或者~/.bashrc
文件,并且修改完之后需要调用source xxx
让该文件生效。
下面在来看一下~/.bashrc
内容
[root@VM_16_15_centos ~]# 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
其实这个文件会调用了/etc/bashrc
文件,所以如果~/.bashrc文件丢失了之后,可能bash的提示字符会变成这样
-bash-4.2$
解决办法就是从其他地方拷贝一份~/.bashrc
文件。
数据流重定向
当执行一个指令的时候,指令可能会从文件读入数据,经过处理之后,将数据输出到屏幕上,输出到屏幕上的数据有可能是正确数据,也有可能是错误的数据。这里就要引入3个概念:
- 标准输入(
stdin
) 代码是0,符号使用<
或者<<
- 标准输出(
stdout
)代码是1,符号使用>
或者>>
- 标准错误输出(
stderr
) 代码是2,符号使用2>
或者2>>
标准输入
标准输入符号可以用来代替键盘输入,比如我们使用cat > filename
创建一个文件的时候,通常需要输入数据需要键盘输入:
[root@VM_16_15_centos ~]# cat > file
aaa
aaa
^C
[root@VM_16_15_centos ~]# cat file
aaa
aaa
同时需要使用ctrl + d
来离开编辑。如果我希望以某个文件为输入源的时候可以这样使用
[root@VM_16_15_centos ~]# cat > file < ~/.bashrc
[root@VM_16_15_centos ~]# cat file
# .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
此时~/bashrc
文件就使用标准输入符号让它作为输入源,关于<<
的使用可以参考下面:
[root@VM_16_15_centos ~]# cat > file << end
> aa
> bb
> end
使用<<
可以在后面加入一个’结束符号’,然后在输入的时候,碰到’结束符号’就会退出编辑(省略了ctrl + d
操作)
标准输出和标准错误输出
标准输出和默认情况下是输出到屏幕的。我们可以通过重定向符号将输出到文件。其中他们的符号如下:
1>
以覆盖的方式将标准输出流输出到指定的文件或者设备上,1可以省略1>>
以追加的方式将标准输出流输出到指定的文件或者设备上,1可以省略2>
以覆盖的方式将标准错误输出流输出到指定的文件或者设备上2>>
以追加的方式将标准错误输出流输出到指定的文件或者设备上
将ll
命令输出结果输出到文件file
中:
[root@VM_16_15_centos ~]# ll / > file
[root@VM_16_15_centos ~]# cat file
total 72
lrwxrwxrwx. 1 root root 7 Jan 9 18:19 bin -> usr/bin
dr-xr-xr-x. 5 root root 4096 Mar 8 15:46 boot
drwxr-xr-x 2 root root 4096 Mar 8 15:45 data
drwxr-xr-x 19 root root 3000 Mar 31 14:20 dev
drwxr-xr-x. 92 root root 12288 Apr 27 11:54 etc
drwxr-xr-x. 3 root root 4096 Mar 31 14:20 home
lrwxrwxrwx. 1 root root 7 Jan 9 18:19 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Jan 9 18:19 lib64 -> usr/lib64
drwx------. 2 root root 16384 Jan 9 18:18 lost+found
drwxr-xr-x. 2 root root 4096 Nov 5 2016 media
drwxr-xr-x. 2 root root 4096 Nov 5 2016 mnt
drwxr-xr-x. 3 root root 4096 Jan 9 18:23 opt
dr-xr-xr-x 117 root root 0 Mar 31 14:20 proc
drwxr-xr-x 5 root root 4096 May 9 17:58 root
drwxr-xr-x 26 root root 940 Apr 14 18:26 run
lrwxrwxrwx. 1 root root 8 Jan 9 18:19 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 Nov 5 2016 srv
dr-xr-xr-x 13 root root 0 Mar 31 14:20 sys
drwxrwxrwt. 9 root root 4096 May 9 18:08 tmp
drwxr-xr-x. 13 root root 4096 Jan 9 18:19 usr
drwxr-xr-x. 20 root root 4096 Apr 19 18:54 var
将ll
命令的标准输出结果输出到right
文件,错误信息输出到error
文件
[root@VM_16_15_centos ~]# ll /root /root1 >right 2>error
[root@VM_16_15_centos ~]# cat right
/root:
total 8
-rw-r--r-- 1 root root 52 May 9 18:32 error
-rw-r--r-- 1 root root 1102 May 9 18:29 file
-rw-r--r-- 1 root root 0 May 9 18:32 right
[root@VM_16_15_centos ~]# cat error
ls: cannot access /root1: No such file or directory
垃圾桶黑洞设备
在Linux系统中,如果我们想将某些信息忽略掉,可以把输出重定向到/dev/null
设备中。就是说所有输出到/dev/null
设备的信息都不会保留。
比如,将ll
命令的标准输出结果丢弃,可以执行以下命令:
ll /root >/dev/null
假如需要将一个命令的标准输出和标准错误输出都输出到某个文件可以这样写:
ll /root /root1 > file 2>&1
上述命令可以这样理解,&1
可以理解为1>
,2>&1
即表示标准错误输出输出到标准输出的地方。
为什么不用ll /root /root1 >file 2>file
这样的方式呢,这样的方式虽然可以将标准输出和标准错误输出输出到file
文件中,但是这两股数据交叉写入会导致顺序错误,所以正确的语法应该是2>&1
这样。
管线
管线使用|
符号,管线的作用在于将一个命令的标准输出结果传递到下一个命令的输入中,例如需要将/etc/
目录的文件分页查询:
ll /etc/ | less
通过管线将/etc/
的文件列表作为less
的输入
使用管线有以下两点需要注意:
- 管线命令仅仅会处理标准输出流,对于标准错误输出不做处理
- 管线命令后面接的命令必须是可以接受数据的命令
下面列出一些管线相关的命令:
cut 命令
cut
的主要用途在于将同一行里面的数据进行分解。比如根据某个字符切割字符。
参数有
d
:后面接分隔字符。与-f
一起使用;f
:依据-d
的分隔字符将一段讯息分区成为数段,用-f
取出第几段的意思;c
:以字符(characters)
的单位取出固定字符区间;
grep 命令
grep
命令的作用是分析一行数据,如果当中有所需的信息,则把该行取出来,并且支持正则表达式。其中参数有:
a
将binary文件以text文件的方式搜索数据c
计算找到匹配字符的次数i
忽略大小小n
输出行号v
:反向选择,亦即显示出没有 ‘搜寻字串’ 内容的那一行--color=auto
:可以将找到的关键字部分加上颜色的显示
sort 命令
sore命令可以对数据进行排序。具有以下参数:
f
忽略大小写b
忽略前面的空白字符M
以月份名字方式来排序n
使用纯数字
进行排序r
反向排序u
相同的数据仅仅显示一次t
分割符号k
以哪个字段进行排序的意思
下面列出一些用法:
对个人账号进行排序输出:
# 默认情况下是按字母排序
cat /etc/passwd | sord
对账号信息以:
分割,并且使用第三列作为排序列
cat /etc/passwd/ | sort -t ':' -k 3
uniq命令
这个命令是对数据重复提供过滤功能。
wc
这个指令用于计算文件中的字、字符、或者行数
列出/etc/man.conf
文件的行数/字数/字符数
cat /etc/man.conf | wc
双向重定向
前面所说的数据重导向只能把数据存到文件或者设备中,但是如果需要在数据处理的过程中,也想看到屏幕输出怎么办?
可以使用tee
命令,tee命令可以在数据处理的过程中,将数据保存为文件,并且数据会继续流向下一个命令。
例如,将/root
目录结果输出到teefile
中并且屏幕也显示结果
ll /root/ | tee -a teefile
总结
本篇文件粗略对Linux
中的shell
知识进行记录,同时主要记录了bash shell
的一些相关特性,文章整理得不是很好,作为学习笔记,勿喷。
以上是关于shell知识点的主要内容,如果未能解决你的问题,请参考以下文章