Linux学习
一、基本命令
路径说明
绝对路径 :以 / 开头
相对路径 :从当前路径下找,相当于找 …/…/
特殊路径 :. 表示当前目录;… 表示上一级目录;~ 表示HOME目录
pwd(显示当前路径)
[root@localhost ~]# pwd
/root
ls(列出目录下内容)
ls :查看当前目录下的所有目录和文件
ls -a :查看所有目录和文件,包含隐藏文件
ls -l :查看所有目录和文件(显示文件的属性和权限详细信息),不包含隐藏文件
ls /目录名 :查看指定目录下所有目录和文件
[root@localhost ~]# pwd
/root
[root@localhost ~]# ls -a
. anaconda-ks.cfg .bash_logout .bashrc .config .dbus .tcshrc
.. .bash_history .bash_profile .cache .cshrc initial-setup-ks.cfg
[root@localhost ~]# ls -l
总用量 8
-rw-------. 1 root root 2064 10月 14 2022 anaconda-ks.cfg
-rw-r--r--. 1 root root 2092 10月 13 2022 initial-setup-ks.cfg
[root@localhost etc]# ls | grep int
fprintd.conf
printcap
cd(切换目录)
cd 路径 :切换到指定路径
cd …/或cd … :切换到上层路径
cd / :切换到根目录
cd ~ :切换到家目录(root用户相当于 cd /root;普通用户cd ~ 相当于cd /home/当前用户名)
cd - :切换到上次访问的目录
[root@localhost ~]# pwd
/root
[root@localhost ~]# cd ..
[root@localhost /]# cd etc
[root@localhost etc]# cd abrt/plugins
[root@localhost plugins]# cd /boot
[root@localhost boot]# cd -
/etc/abrt/plugins
[root@localhost plugins]# cd ~
[root@localhost ~]# cd /
[root@localhost /]#
mkdir(创建目录)
mkdir 目录名:在当前路径下创建目录
mkdir /test1/test2:在指定路径下创建目录
[root@localhost /]# mkdir /test1
[root@localhost /]# cd test1
[root@localhost test1]# cd ..
[root@localhost /]# mkdir /test1/test2
[root@localhost /]# cd /test1/test2
[root@localhost test2]#
rmdir(删除目录)
rmdir 目录名 : 删除指定目录
rmdir -p 目录名 :强制删除指定的目录
[root@localhost /]# mkdir /test3
[root@localhost /]# rmdir test3
[root@localhost /]# cd /test3
-bash: cd: /test3: 没有那个文件或目录
touch(创建文件)
touch 文件名:在当前目录下创建指定名称的文件,如果文件存在,将文件时间属性修改为当前系统时间
[root@localhost test2]# touch a.txt
[root@localhost test2]# touch b.txt
[root@localhost test2]# ls
a.txt b.txt
rm(删除目录或文件)
rm 文件名 :删除当前目录下的文件(y-删除,n-不删除)
rm -f 文件名 :删除当前目录的的文件,不做询问
rm -r 目录名 :递归删除当前目录下指定名称的目录(y-删除,n-不删除)
rm -rf 目录名 :递归删除当前目录下指定名称的目录,不做询问
rm -rf * :将当前目录下的所有目录和文件全部删除
rm -rf /* :将根目录下的所有文件全部删除,相当于格式化系统,轻易不用
[root@localhost test2]# rm a.txt
rm:是否删除普通空文件 "a.txt"?y
[root@localhost test2]# rm b.txt
rm:是否删除普通空文件 "b.txt"?n
[root@localhost test2]# rm -f b.txt
[root@localhost test2]# cd ..
[root@localhost test1]# rm -rf test2
[root@localhost test1]# cd test2
-bash: cd: test2: 没有那个文件或目录
cp(复制文件目录)
cp 文件路径 新路径 :复制指定文件至新目录
cp -r 目录路径 新路径 :递归复制目录下所有文件和文件夹至新目录
如果复制行为中文件重复,就选则输入y进行覆盖或者输入n放弃复制
[root@localhost test1]# cp -r /test1/tool /test2
[root@localhost test1]# cd /test2
[root@localhost test2]# ls -l
总用量 0
drwxr-xr-x. 2 root root 21 10月 3 21:20 tool
[root@localhost test2]# cp /test1/a.txt /test2
[root@localhost test2]# ls -l
总用量 0
-rw-r--r--. 1 root root 0 10月 3 21:21 a.txt
drwxr-xr-x. 2 root root 21 10月 3 21:20 tool
[root@localhost test2]# cp /test1/a.txt /test2
cp:是否覆盖"/test2/a.txt"? y
mv(修改目录)
mv 目录名 新目录名 :修改目录名
mv 文件名 新文件名 :修改文件名
mv 文件名 新路径 :将文件移动至指定路径下
[root@localhost /]# mv /test1 /demo1
[root@localhost /]# cd demo1
[root@localhost demo1]# cd test1
-bash: cd: test1: 没有那个文件或目录
[root@localhost /]# cd demo1
[root@localhost demo1]# ls
a.txt p.txt tool
[root@localhost demo1]# mv /demo1/p.txt /test2
[root@localhost demo1]# cd /demo1
[root@localhost demo1]# ls
a.txt tool
[root@localhost demo1]# cd /test2
[root@localhost test2]# ls
a.txt p.txt tool
tar -zcvf(打包文件及解压文件)
.zip、.rar——windows系统中压缩文件的扩展名
.tar ——Linux中打包文件的扩展名
.gz——Linux中压缩文件的扩展名
.tar.gz——Linux中打包并压缩文件的扩展名
tar -zcvf 打包压缩后的文件名 文件1 文件2,… :将指定文件压缩打包
tar -zcvf 压缩文件名 :将指定压缩文件解压至当前目录
tar -zcvf 压缩文件名 -C 指定路径 :将指定压缩文件解压至指定路径下
[root@localhost /]# cd /test2
[root@localhost test2]# tar -zcvf a.tar p.txt
p.txt
[root@localhost test2]# ls
a.tar a.txt p.txt tool
[root@localhost test2]# tar -zxvf a.tar -C /test3
p.txt
[root@localhost test2]# cd /test3
[root@localhost test3]# ls
p.txt
grep(查找字符串或正则表达式)
grep [options] pattern [files] :查找文件里符合条件的字符串或正则表达式
pattern:要查找的字符串或正则表达式。
files:为要查找的文件名,可以同时查找多个文件,如果省略 files 参数,则默认从标准输入中读取数据。
options:
-i:忽略大小写进行匹配。
-v:反向查找,只打印不匹配的行。
-n:显示匹配行的行号。
-r:递归查找子目录中的文件。
-l:只打印匹配的文件名。
-c:只打印匹配的行数。
可配合其他命令一起使用
[root@localhost test2]# cd /etc
[root@localhost etc]# ls | grep ini
gdbinit
gdbinit.d
init.d
inittab
find(查找文件和目录)
find [路径] [参数] :查找指定目录下的文件和目录。
路径:可以是一个目录或文件名,也可以是多个路径,多个路径之间用空格分隔,如果未指定路径,则默认为当前目录。
参数:
用于指定查找的条件,可以是文件名、文件类型、文件大小等,可用选项很多,。
top(显示当前系统中占用资源最多的一些进程)
top - 22:14:30 up 5:12, 4 users, load average: 0.00, 0.04, 0.06
Tasks: 223 total, 1 running, 222 sleeping, 0 stopped, 0 zombie
top - 22:16:12 up 5:14, 4 users, load average: 0.00, 0.03, 0.06
Tasks: 224 total, 1 running, 223 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.0 us, 3.3 sy, 0.0 ni, 93.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2027864 total, 84600 free, 815988 used, 1127276 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 1024372 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2376 vm1 20 0 3018988 184236 67616 S 0.3 9.1 0:08.88 gnome-shell
2740 vm1 20 0 1118792 55120 22524 S 0.0 2.7 0:01.52 gnome-software
1446 root 20 0 315356 43420 23584 S 0.0 2.1 0:01.17 X
2668 vm1 20 0 1047076 31984 19420 S 0.0 1.6 0:00.32 nautilus-deskto
进程信息:
PID:进程的标识符。
USER:运行进程的用户名。
PR(优先级):进程的优先级。
NI(Nice值):进程的优先级调整值。
VIRT(虚拟内存):进程使用的虚拟内存大小。
RES(常驻内存):进程实际使用的物理内存大小。
SHR(共享内存):进程共享的内存大小。
%CPU:进程占用 CPU 的使用率。
%MEM:进程占用内存的使用率。
TIME+:进程的累计 CPU 时间。
Shell命令:
echo 字符串 :在终端输出指定字符串
[root@localhost ~]# echo "test"
test
printf 格式控制字符串 [参数列表]
printf "name:%s sex:%s height:%.2f" 石敢当 男
name:石敢当 sex:男 height:112.30
小tips:
做操作目录未更新,想看最新目录结构可右击刷新获取最新结构
vi/vim 编辑器
vi 文件名 :打开需要编辑的文件
进入文件后有三种模式:命令模式;插入模式;底行模式
无论处于那种工作模式,按 Esc键都可进入命令模式。插入模式和底行模式不能直接切换,需要经过命令模式
命令模式
vi加文件名进入文件即处于命令模式,需要通过键盘的四个方向键控制光标位置。
其他模式下按 Esc键进入命令模式。
按动“gg” :光标跳至文首
按动“G” :光标跳至文末
按动“dd” :删除光标所在行,“行数dd”即删除光标所在行在内及以下的行,共指定行数的内容
按动“x”或[Del]:删除光标后一个字符,“字符数x”即删除光标后指定字符数个字符字符
按动“X”:删除光标前一个字符
按动“行数yy” :复制光标以下指定行数的内容
按动“p” :将粘贴板的数据粘贴在光标所在行的上一行,原光标所在行会被推后一行
输入命令“/字符串” :查找含指定字符串的行,每次显示一处,按动"n"跳到下一处,直至提示找不到。
按动.(小数点) :重复前一个操作
进入插入模式:
在命令模式下按o或O :在光标所在行的下面另起一新行插入
在命令模式下按i或I :在光标所在处开始插入
在命令模式下按a或A :在光标所在处的后一个字符开始插入
在命令模式下按r或R :取代模式插入。r 只会取代光标所在处的字符一次;R会一直取代光标所在处的字符,直到退出插入模式为止。
进入底行模式:
在命令模式下按":" :进入底行模式
插入模式
可对文件进行内容进行插入操作,直接输入想插入的内容即可。
底行模式
输入q(即:q)回车执行:退出编辑,不做保存
输入q!(即:q!)回车执行:不管有没有做编辑,都强制退出编辑,不做保存
输入wq(即:wq)回车执行:保存并退出编辑
演示示例
我们接下来复制一个文件进行操作演示(新建vitest文件夹,将/etc/man_db.conf文件复制进来并命名mn_dbpp):
[root@localhost etc]# cd /
[root@localhost /]# mkdir vitest
[root@localhost /]# cp /etc/man_db.conf /vitest/mn_dbpp
[root@localhost /]# cd /vitest
[root@localhost vitest]# cat man_dbpp
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
# their PATH environment variable. For details see the manpath(5) man page.
#
# Lines beginning with `#' are comments and are ignored. Any combination of
# tabs or spaces may be used as `whitespace' separators.
#
# There are three mappings allowed in this file:
# --------------------------------------------------------
# MANDATORY_MANPATH manpath_element
# MANPATH_MAP path_element manpath_element
# MANDB_MAP global_manpath [relative_catpath]
#---------------------------------------------------------
# every automatically generated MANPATH includes these fields
#
#MANDATORY_MANPATH /usr/src/pvm3/man
#
MANDATORY_MANPATH /usr/man
MANDATORY_MANPATH /usr/share/man
MANDATORY_MANPATH /usr/local/share/man
#---------------------------------------------------------
# set up PATH to MANPATH mapping
# ie. what man tree holds man pages for what binary directory.
#
# *PATH* -> *MANPATH*
#
MANPATH_MAP /bin /usr/share/man
MANPATH_MAP /usr/bin /usr/share/man
MANPATH_MAP /sbin /usr/share/man
MANPATH_MAP /usr/sbin /usr/share/man
MANPATH_MAP /usr/local/bin /usr/local/man
MANPATH_MAP /usr/local/bin /usr/local/share/man
MANPATH_MAP /usr/local/sbin /usr/local/man
MANPATH_MAP /usr/local/sbin /usr/local/share/man
MANPATH_MAP /usr/X11R6/bin /usr/X11R6/man
MANPATH_MAP /usr/bin/X11 /usr/X11R6/man
MANPATH_MAP /usr/games /usr/share/man
MANPATH_MAP /opt/bin /opt/man
MANPATH_MAP /opt/sbin /opt/man
#---------------------------------------------------------
# For a manpath element to be treated as a system manpath (as most of those
# above should normally be), it must be mentioned below. Each line may have
# an optional extra string indicating the catpath associated with the
# manpath. If no catpath string is used, the catpath will default to the
# given manpath.
#
# You *must* provide all system manpaths, including manpaths for alternate
# operating systems, locale specific manpaths, and combinations of both, if
# they exist, otherwise the permissions of the user running man/mandb will
# be used to manipulate the manual pages. Also, mandb will not initialise
# the database cache for any manpaths not mentioned below unless explicitly
# requested to do so.
#
# In a per-user configuration file, this directive only controls the
# location of catpaths and the creation of database caches; it has no effect
# on privileges.
#
# Any manpaths that are subdirectories of other manpaths must be mentioned
# *before* the containing manpath. E.g. /usr/man/preformat must be listed
# before /usr/man.
#
# *MANPATH* -> *CATPATH*
#
MANDB_MAP /usr/man /var/cache/man/fsstnd
MANDB_MAP /usr/share/man /var/cache/man
MANDB_MAP /usr/local/man /var/cache/man/oldlocal
MANDB_MAP /usr/local/share/man /var/cache/man/local
MANDB_MAP /usr/X11R6/man /var/cache/man/X11R6
MANDB_MAP /opt/man /var/cache/man/opt
#
#---------------------------------------------------------
# Program definitions. These are commented out by default as the value
# of the definition is already the default. To change: uncomment a
# definition and modify it.
#
#DEFINE pager less -s
#DEFINE cat cat
#DEFINE tr tr '\255\267\264\327' '\055\157\047\170'
#DEFINE grep grep
#DEFINE troff groff -mandoc
#DEFINE nroff nroff -mandoc -c
#DEFINE eqn eqn
#DEFINE neqn neqn
#DEFINE tbl tbl
#DEFINE col col
#DEFINE vgrind
#DEFINE refer refer
#DEFINE grap
#DEFINE pic pic -S
#
#DEFINE compressor gzip -c7
#---------------------------------------------------------
# Misc definitions: same as program definitions above.
#
#DEFINE whatis_grep_flags -i
#DEFINE apropos_grep_flags -iEw
#DEFINE apropos_regex_grep_flags -iE
#---------------------------------------------------------
# Section names. Manual sections will be searched in the order listed here;
# the default is 1, n, l, 8, 3, 0, 2, 5, 4, 9, 6, 7. Multiple SECTION
# directives may be given for clarity, and will be concatenated together in
# the expected way.
# If a particular extension is not in this list (say, 1mh), it will be
# displayed with the rest of the section it belongs to. The effect of this
# is that you only need to explicitly list extensions if you want to force a
# particular order. Sections with extensions should usually be adjacent to
# their main section (e.g. "1 1mh 8 ...").
#
SECTION 1 1p 8 2 3 3p 4 5 6 7 9 0p n l p o 1x 2x 3x 4x 5x 6x 7x 8x
#
#---------------------------------------------------------
# Range of terminal widths permitted when displaying cat pages. If the
# terminal falls outside this range, cat pages will not be created (if
# missing) or displayed.
#
#MINCATWIDTH 80
#MAXCATWIDTH 80
#
# If CATWIDTH is set to a non-zero number, cat pages will always be
# formatted for a terminal of the given width, regardless of the width of
# the terminal actually being used. This should generally be within the
# range set by MINCATWIDTH and MAXCATWIDTH.
#
#CATWIDTH 0
#
#---------------------------------------------------------
# Flags.
# NOCACHE keeps man from creating cat pages.
#NOCACHE
我们复制成功并对文件内容做显示,这是文件的初始内容。
[root@localhost vitest]# vi man_dbpp
#
# There are three mappings allowed in this file:
# --------------------------------------------------------
# MANDATORY_MANPATH manpath_element
# MANPATH_MAP path_element manpath_element
# MANDB_MAP global_manpath [relative_config]
vi man_dbpp进入vi man_dbpp文件,我们当前处于命令模式。
1.将文本中所有的“catpath”字符串替换成“config”
按动i进入插入模式,但左下方可以直接输入的。
直接输入命令:1,$s/catpath/config/g,回车执行,进行替换操作,显示如下提示信息。
$也可以用%代替;s前可加数字,如20s,代表替换范围为光标以下20行;/catpath为原字符串;/config意为将原字符串替换为config新字符串;g表示全局,则进行全局替换。
# Any manpaths that are subdirectories of other manpaths must be mentioned
# *before* the containing manpath. E.g. /usr/man/preformat must be listed
# before /usr/man.
#
5 substitutions on 4 lines
2.复制第1~17行的内容,并且贴到文件最后一行后
首先移动光标至第1行。按动gg键,光标即直接移动至文首,即第1行。
输入17yy,复制17行内容,显示如下提示信息。
17 lines yanked
按G光标到文末,按动p进行粘贴,就将复制内容粘到最后一行的后面了,显示如下提示信息
17 more lines
文末也添加了17行新内容
3.删除第5行内容
#
#
# This file is used by the man-db package to configure the man and cat paths.
# It is also used to provide a manpath for those without one by examining
[光标]# their PATH environment variable. For details see the manpath(5) man page.
#
按动行号5并按G,即可跳到指定行,按动dd可删除光标所在行
4.删除所有‘#’
参考1中的命令,将命令调整为:1,$s/#//g,原字符串为#,就会查找所有#,新字符串处无内容即可起到删除的效果,显示如下提示信息。
126 substitutions on 124 lines
5.删除包含有字符串“conf”的那几行
输入命令/conf,光标跳到字符串所在行;
按动dd删除该行;
按动n跳到含conf字符串的下一行,逐次删除。
6.在第一行新增一行文字内容
按动gg跳至文首;
按动i进入编辑模式;
输入内容即可看到效果。
团圆美满充满希望
This file is used by the man-db package to configure the man and cat paths.
It is also used to provide a manpath for those without one by examining
6.将文件另存为new_man_db.conf
按动:进入底行模式;
输入wq new_man_db(即:wq new_man_db)回车执行,则另存成功,显示如下信息。
"new_man_db" [New] 128L, 4966C written
E37: No write since last change
E162: No write since last change for buffer "man_dbpp"
Press ENTER or type command to continue
账号管理
Linux采用多用户的管理模式进行权限管理,任何想要使用系统资源的用户都要先向系统管理员申请一个账号,以账号身份进入系统。
Linux中一切接文件添加用户就是往某个文件中写入用户的信息。
root用户拥有最大权限。
普通用户在很多地方权限是有限制的,一般在它的home目录里是不受限的,home目录以外,就仅有只读和执行的权限,无权修改。
Linux系统中可以配置多个用户;配置多个用户组;用户可以同时加入不同的用户组中。可以对用户的权限做控制,也可以对用户组的权限做控制。
groupadd(创建用户组)
groupadd 用户组名 :创建用户组
[root@localhost home]# groupadd tymm
groupdel(删除用户组)
groupdel 用户组名 :删除用户组
[root@localhost home]# groupdel tymm
useradd(添加用户)
useradd -m 用户名 :自动创建这个用户的主目录 /home/用户名。Linux中一切皆文件,添加用户即创建新文件来保存用户的信息。
useradd -G 用户名 :给用户分配组;
[root@localhost ~]# useradd -m user1
[root@localhost ~]# cd /home
[root@localhost home]# ls
user1 vm1
id(添加用户)
id :查看自身用户所属用户组
id 用户名 :查看指定用户所属用户组
[root@localhost home]# id user2
uid=1001(user2) gid=1001(user2) 组=1001(user2)
usermod(修改用户所属组)
usermod -aG 用户组 用户名 :修改用户所属组至指定用户组
[root@localhost home]# groupadd tymm
[root@localhost home]# usermod -aG tymm user2
userdel(删除用户)
userdel -r 用户名 :删除用户,将他的目录删除
[root@localhost home]# userdel -r user1
[root@localhost home]# ls
vm1
getent(查看系统中的用户)
getent passwd :查看当前系统中有那些用户。
显示各个用户的七种信息:用户名/密码/用户ID/组ID/描述信息/HOME目录/执行终端(默认bash)
[root@localhost home]# getent passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
saned:x:996:993:SANE scanner daemon user:/usr/share/sane:/sbin/nologin
gluster:x:995:992:GlusterFS daemons:/run/gluster:/sbin/nologin
saslauth:x:994:76:Saslauthd user:/run/saslauthd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
setroubleshoot:x:993:990::/var/lib/setroubleshoot:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
chrony:x:992:987::/var/lib/chrony:/sbin/nologin
unbound:x:991:986:Unbound DNS resolver:/etc/unbound:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
sssd:x:990:984:User for sssd:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
geoclue:x:989:983:User for geoclue:/var/lib/geoclue:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:988:982::/run/gnome-initial-setup/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
vm1:x:1000:1000:vm1:/home/vm1:/bin/bash
user2:x:1001:1001::/home/1123:/bin/bash
su(切换用户)
su 用户名:切换至指定用户。
在终端输入 exit 或按动 [ctrl]+d,可以退回到原来用户
[root@localhost home]# su user2
bash-4.2$ su root
密码:
[root@localhost home]#
输入密码时不显示的,不用管,直接输入,输入结束回车即可
$表示普通用户,#表示root用户。
切换用户时如果想在切换用户后使用新用户的工作环境,可以在su和用户名之间加 - ,如:su - root
-bash-4.2$ su - root
密码:
上一次登录:四 10月 5 17:43:28 CST 2023pts/1 上
[root@localhost ~]#
passwd(修改用户密码)
passwd 用户名 :root用户使用,可指定用户名去修改密码。
passwd :普通用户使用,修改当下用户的密码。
passwd -l qinjiang 用户名 :root用户使用,锁定此用户,此后不能登录
passwd -l qinjiang 用户名 :root用户使用,锁定此用户,此后不能登录
[root@localhost home]# passwd user2
更改用户 user2 的密码 。
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost home]# su user2
bash-4.2$ passwd
更改用户 user2 的密码 。
为 user2 更改 STRESS 密码。
(当前)UNIX 密码:
新的 密码:
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
密码输入依旧不显示,直接输入就好了,输入完毕回车执行。
ls -l(查看权限控制信息)
ls -l :以列表形式查看内容,并显示权限细节
[root@localhost /]# ls -l
总用量 24
lrwxrwxrwx. 1 root root 7 10月 14 2022 bin -> usr/bin
dr-xr-xr-x. 5 root root 4096 10月 14 2022 boot
drwxr-xr-x. 3 root root 31 10月 3 21:45 demo1
drwxr-xr-x. 20 root root 3340 10月 5 13:48 dev
drwxr-xr-x. 144 root root 8192 10月 5 19:25 etc
drwxr-xr-x. 4 root root 30 10月 5 17:28 home
lrwxrwxrwx. 1 root root 7 10月 14 2022 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 10月 14 2022 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 6 4月 11 2018 media
drwxr-xr-x. 2 root root 6 4月 11 2018 mnt
drwxr-xr-x. 3 root root 16 10月 14 2022 opt
dr-xr-xr-x. 240 root root 0 10月 5 13:48 proc
dr-xr-x---. 5 root root 205 9月 28 01:37 root
drwxr-xr-x. 43 root root 1280 10月 5 20:16 run
lrwxrwxrwx. 1 root root 8 10月 14 2022 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 4月 11 2018 srv
dr-xr-xr-x. 13 root root 0 10月 5 13:48 sys
drwxr-xr-x. 3 root root 85 10月 4 22:29 test2
drwxr-xr-x. 2 root root 19 10月 4 22:31 test3
drwxrwxrwt. 37 root root 4096 10月 5 17:49 tmp
drwxr-xr-x. 13 root root 155 10月 14 2022 usr
drwxr-xr-x. 21 root root 4096 10月 14 2022 var
drwxr-xr-x. 2 root root 53 10月 4 22:15 vitest
以第一行为例,lrwxrwxrwx. 1 root root
lrwxrwxrwx位置表示文件或文件夹或软连接的权限控制信息;
第一个root表示文件或文件夹或软连接所属用户;
第二个root表示文件或文件夹或软连接所属用户组;
权限细节:
r为读权限:可以查看文件文件夹内容,可以执行如ls命令;
w为写权限:可以修改此文件或文件夹(可对文件夹内进行创建、删除改名操作);
x为执行权限:可以执行此文件或更改目录到此文件夹文件夹。
如lrwxrwxrwx表示:
l——这是一个软连接;
rwx——所属用户拥有读权限、写权限和执行权限;
rwx——所属用户组拥有读权限、写权限和执行权限;
rwx——其他用户拥有读权限、写权限和执行权限;
如drwxr-xr-x表示:
d——这是一个文件夹;
rwx——所属用户拥有读权限、写权限和执行权限;
xr——所属用户组拥有读权限和执行权限,没有写权限;
x——其他用户拥有执行权限,没有读权限和写权限;
chmod(修改权限控制信息)
chmod 新权限 [-R] 文件或文件夹 :修改文件、文件夹的权限信息
-R:若有-R则对文件夹内的全部内容应用同样的操作。
不过只有文件或文件夹所属用户或拥有最大权限的root用户可以执行执行修改命令
修改文件权限:
[root@localhost /]# touch test.txt
[root@localhost /]# ls
可看到文件当前属性:
-rw-r--r--. 1 root root 0 10月 5 23:15 test.txt
将其权限修改为:rwxr-x–x
[root@localhost /]# chmod u=rwx,g=rx,o=x test.txt
再去查看文件属性:
-rwxr-x--x. 1 root root 0 10月 5 23:15 test.txt
修改文件夹权限:
将文件夹内的全部内容权限都修改为 rwxr-x–x
[root@localhost /]# chmod -R u=rwx,g=rx,o=x test2
[root@localhost /]# cd /test2
[root@localhost test2]# ls -l
总用量 12
-rwxr-x--x. 1 root root 109 10月 4 22:16 a.tar
-rwxr-x--x. 1 root root 0 10月 3 21:26 a.txt
-rwxr-x--x. 1 root root 0 10月 3 21:43 p.txt
drwxr-x--x. 2 root root 21 10月 3 21:20 tool
-rwxr-x--x. 1 root root 109 10月 4 22:29 tp1.gz
-rwxr-x--x. 1 root root 109 10月 4 22:29 tp.zip
可看到test2文件夹内所有内容权限都为 rwxr-x–x。
权限数字表示含义:
权限可以用3位数字来代表,第一位数字表示用户权限,第二位表示用户组权限,第三位表示其它用户权限。数字的细节为:r记为4, w记为2,x记为1,则:
数字 | 含义 |
---|---|
0 | 无任何权限,即- |
1 | 仅有x权限,即–x |
2 | 仅有w权限,即-w- |
3 | 有w和x权限,即-wx |
4 | 仅有r权限,即r– |
5 | 有r和x权限,即r-x |
6 | 有r和w权限,即rw- |
7 | 有全部权限,即rwx |
chown(修改权限控制)
chown [-R] [用户][:][用户组]文件或文件夹 :可以修改文件或文件夹的所属用户和用户组
-R:若有-R则对文件夹内的全部内容应用同样的操作。
用户 :修改所属用户
: :分隔用户和用户组
用户组 :修改所属用户组
修改文件权限:
[root@localhost /]# chown user2 test.txt
[root@localhost /]# ls -l
可看到test.txt文件所属用户为user2
-rwxr-x--x. 1 user2 root 0 10月 5 23:15 test.txt
修改文件夹权限:
[root@localhost /]# chown -R user2 test2
[root@localhost /]# cd /test2
[root@localhost test2]# ls -l
总用量 12
-rwxr-x--x. 1 user2 root 109 10月 4 22:16 a.tar
-rwxr-x--x. 1 user2 root 0 10月 3 21:26 a.txt
-rwxr-x--x. 1 user2 root 0 10月 3 21:43 p.txt
drwxr-x--x. 2 user2 root 21 10月 3 21:20 tool
-rwxr-x--x. 1 user2 root 109 10月 4 22:29 tp1.gz
-rwxr-x--x. 1 user2 root 109 10月 4 22:29 tp.zip
可看到test2文件夹内所属用户都为user2
磁盘管理(今日补充)
磁盘管理常用三个命令:
df:列出文件系统的整体磁盘使用量
du:检查磁盘空间使用量
fdisk:用于磁盘分区
df命令
语法格式:
df [选项] [目录或文件]
可选选项及含义:
- -a :列出所有的文件系统,包括系统特有的 /proc 等文件系统
- -k :以 KBytes 的容量显示各文件系统
- -m :以 MBytes 的容量显示各文件系统
- -h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示
- -H :以 M=1000K 取代 M=1024K 的进位方式
- -T :显示文件系统类型, 连同该 partition 的 filesystem 名称 (例如 ext3) 也列出
- -i :不用硬盘容量,而以 inode 的数量来显示
- 不加选项:默认将系统内所有的文件系统 (不含特殊内存内的文件系统与 swap) 都以 1 Kbytes 的容量来列出来
df命令列出系统内所有的文件系统,执行演示:
[root@localhost ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
devtmpfs 996908 0 996908 0% /dev
tmpfs 1013932 0 1013932 0% /dev/shm
tmpfs 1013932 10692 1003240 2% /run
tmpfs 1013932 0 1013932 0% /sys/fs/cgroup
/dev/mapper/centos-root 10475520 5619276 4856244 54% /
/dev/sda1 201380 153000 48380 76% /boot
/dev/mapper/centos-home 508580 31232 477348 7% /home
tmpfs 202788 24 202764 1% /run/user/1000
/dev/sr0 4600876 4600876 0 100% /run/media/vm1/CentOS 7 x86_64
tmpfs 202788 0 202788 0% /run/user/0
df -h命令将容量结果以易读的容量格式显示出来,执行演示:
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 974M 0 974M 0% /dev
tmpfs 991M 0 991M 0% /dev/shm
tmpfs 991M 11M 980M 2% /run
tmpfs 991M 0 991M 0% /sys/fs/cgroup
/dev/mapper/centos-root 10G 5.4G 4.7G 54% /
/dev/sda1 197M 150M 48M 76% /boot
/dev/mapper/centos-home 497M 31M 467M 7% /home
tmpfs 199M 24K 199M 1% /run/user/1000
...
可以添加文件夹名,即df -h 文件夹,如df -h /etc,指定文件夹,便可将指定文件夹容量结果以易读的容量格式显示。
df -aT命令将系统内的所有特殊文件格式及名称都列出来,执行演示:
[root@localhost ~]# df -aT
文件系统 类型 1K-块 已用 可用 已用% 挂载点
sysfs sysfs 0 0 0 - /sys
proc proc 0 0 0 - /proc
devtmpfs devtmpfs 996908 0 996908 0% /dev
securityfs securityfs 0 0 0 - /sys/kernel/security
tmpfs tmpfs 1013932 0 1013932 0% /dev/shm
...
du命令
直接到文件系统内去搜寻所有的文件数据。
语法格式:
du [选项] 文件或目录
可选选项及含义:
- -a :列出所有的文件与目录容量,默认仅统计目录底下的文件量
- -h :以人们较易读的容量格式 (G/M) 显示
- -s :列出总量
- -S :与 -s不同的是,不包括子目录下的总计
- -k :以 KBytes 列出容量显示
- m :以 KBytes 列出容量显示
du命令列出当前目录下的所有文件夹容量,包括隐藏文件夹,执行演示:
[root@localhost ~]# du
4 ./.cache/dconf
4 ./.cache/abrt
8 ./.cache
4 ./.dbus/session-bus
4 ./.dbus
0 ./.config/abrt
0 ./.config
8 ./demo
56 .
可见会显示当前所在目录里的子目录所占用的硬盘空间。
du -a命令列出当前目录下的所有文件和文件夹容量,执行演示:
[root@localhost ~]# du -a
4 ./.bash_logout
4 ./.bash_profile
4 ./.bashrc
4 ./.cshrc
4 ./.tcshrc
4 ./anaconda-ks.cfg
4 ./.cache/dconf/user
4 ./.cache/dconf
4 ./.cache/abrt/lastnotification
4 ./.cache/abrt
8 ./.cache
...
**du -sm /***命令检查根目录底下每个目录所占用的容量,执行演示:
0 /srv
0 /sys
1 /test2
0 /test3
0 /test.txt
1 /tmp
3963 /usr
1377 /var
fdisk命令
作为磁盘分区表操作工具。
语法格式:
fdisk [选项] 装置名称
可选选项及含义:
- -l :输出后面接的装置所有的分区内容,若不指定装置名称,则系统把整个系统内能够搜寻到的装置的分区均列出
fdisk -l命令列出所有分区信息
[root@localhost ~]# fdisk -l
磁盘 /dev/sda:21.5 GB, 21474836480 字节,41943040 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x000e7d99
设备 Boot Start End Blocks Id System
/dev/sda1 * 2048 411647 204800 83 Linux
/dev/sda2 411648 26617855 13103104 8e Linux LVM
磁盘 /dev/mapper/centos-root:10.7 GB, 10737418240 字节,20971520 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘 /dev/mapper/centos-swap:2147 MB, 2147483648 字节,4194304 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘 /dev/mapper/centos-home:524 MB, 524288000 字节,1024000 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
找出你系统中的根目录所在磁盘,并查阅该硬盘内的相关信息,实例演示:
[root@localhost ~]# df /
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/centos-root 10475520 5618036 4857484 54% /
找出磁盘文件名
[root@localhost ~]# fdisk /dev/mapper/centos-root
欢迎使用 fdisk (util-linux 2.23.2)。
更改将停留在内存中,直到您决定将更改写入磁盘。
使用写入命令前请三思。
Device does not contain a recognized partition table
使用磁盘标识符 0xe87440fb 创建新的 DOS 磁盘标签。
命令(输入 m 获取帮助):
键入 m:
命令(输入 m 获取帮助):m
命令操作
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
键入p,输出目前磁盘的状态:
命令(输入 m 获取帮助):p
磁盘 /dev/mapper/centos-root:10.7 GB, 10737418240 字节,20971520 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0xe87440fb
设备 Boot Start End Blocks Id System
键入q即可不储存并离开
软件安装
yum命令
yum命令需要root权限,且需要联网。
yum:RPM包软件管理器,能够从指定的服务器自动下载 RPM 包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。提供了查找、安装、删除某一个、一组甚至全部软件包的命令。
yum [-y] [install | remove | search] 软件名称:自动化安装配置Linux软件。
-y :自动确认安装或卸载操作,无需手动确认
install:安装
remove:卸载
search:搜索是否有该软件
安装gedit
[root@localhost /]# yum install gedit
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.nju.edu.cn
* extras: mirrors.nju.edu.cn
* updates: mirrors.qlu.edu.cn
base | 3.6 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
软件包 2:gedit-3.28.1-3.el7.x86_64 已安装并且是最新版本
无须任何处理
安装Nginx
1.安装编译工具及库文件:
[root@localhost ~]# yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
......
更新完毕:
zlib.x86_64 0:1.2.7-21.el7_9
作为依赖被升级:
glibc.x86_64 0:2.17-326.el7_9 glibc-common.x86_64 0:2.17-326.el7_9
krb5-libs.x86_64 0:1.15.1-55.el7_9 krb5-workstation.x86_64 0:1.15.1-55.el7_9
libkadm5.x86_64 0:1.15.1-55.el7_9 openssl.x86_64 1:1.0.2k-26.el7_9
openssl-libs.x86_64 1:1.0.2k-26.el7_9
完毕!
2.安装 PCRE(让 Nginx 支持 Rewrite 功能)
[root@localhost ~]# cd /usr/local/src/
[root@localhost src]# wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
--2023-10-06 22:50:31-- http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
正在解析主机 downloads.sourceforge.net (downloads.sourceforge.net)... 204.68.111.105
.....
正在保存至: “pcre-8.35.tar.gz”
100%[==========================================================>] 1,996,552 99.8KB/s 用时 27s
2023-10-06 22:51:00 (72.1 KB/s) - 已保存 “pcre-8.35.tar.gz” [1996552/1996552])
3.解压安装包
[root@localhost src]# tar zxvf pcre-8.35.tar.gz
pcre-8.35/
pcre-8.35/pcre_scanner.h
pcre-8.35/LICENCE
4.进入安装包目录
[root@localhost src]# cd pcre-8.35
5.编译安装
[root@localhost pcre-8.35]# ./configure
[root@localhost pcre-8.35]# make && make install
......
ln -sf pcre_utf32_to_host_byte_order.3 /usr/local/share/man/man3/pcre32_utf32_to_host_byte_order.3
ln -sf pcre_version.3 /usr/local/share/man/man3/pcre32_version.3
make[3]: 离开目录“/usr/local/src/pcre-8.35”
make[2]: 离开目录“/usr/local/src/pcre-8.35”
make[1]: 离开目录“/usr/local/src/pcre-8.35”
6.查看pcre版本
[root@localhost pcre-8.35]# pcre-config --version
8.35
6.安装 Nginx
[root@localhost pcre-8.35]# cd /usr/local/src/
[root@localhost src]# wget http://nginx.org/download/nginx-1.6.2.tar.gz
--2023-10-06 22:58:52-- http://nginx.org/download/nginx-1.6.2.tar.gz
正在解析主机 nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5704::6, ...
正在连接 nginx.org (nginx.org)|3.125.197.172|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:804164 (785K) [application/octet-stream]
正在保存至: “nginx-1.6.2.tar.gz”
100%[==========================================================>] 804,164 81.3KB/s 用时 11s
2023-10-06 22:59:05 (72.2 KB/s) - 已保存 “nginx-1.6.2.tar.gz” [804164/804164])
7.解压安装包
[root@localhost src]# tar zxvf nginx-1.6.2.tar.gz
nginx-1.6.2/
nginx-1.6.2/auto/
nginx-1.6.2/conf/
8.进入安装包目录
[root@localhost src]# cd nginx-1.6.2
9.编译安装
[root@localhost nginx-1.6.2]# ./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/src/pcre-8.35
checking for OS
+ Linux 3.10.0-1160.el7.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
......
[root@localhost nginx-1.6.2]# make
......
[root@localhost nginx-1.6.2]# make install
......
10.查看nginx版本
[root@localhost nginx-1.6.2]# /usr/local/webserver/nginx/sbin/nginx -v
nginx version: nginx/1.6.2
nginx安装完成
11.进行nginx配置
创建 Nginx 运行使用的用户 www:
[root@localhost nginx-1.6.2]# /usr/sbin/groupadd www
[root@localhost nginx-1.6.2]# /usr/sbin/useradd -g www www
配置nginx.conf ,将/usr/local/webserver/nginx/conf/nginx.conf替换为以下内容(我用的vi编辑,删除原内容,粘贴新内容,:wq保存退出):
[root@localhost nginx-1.6.2]# cat /usr/local/webserver/nginx/conf/nginx.conf
[root@localhost nginx-1.6.2]# vi /usr/local/webserver/nginx/conf/nginx.conf
检查配置文件nginx.conf的正确性命令:
[root@localhost nginx-1.6.2]# /usr/local/webserver/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/webserver/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/webserver/nginx/conf/nginx.conf test is successful
Shell
Shell是用C语言编写的程序,是用户使用linux的桥梁,它既是一种命令语言,也是一种程序设计语言。Shall指一种应用程序,这个应用程序提供了一种界面,用户通过这个界面访问操作系统内核的服务。
Shell脚本是一种为shell编写的脚本程序。shell通常都是指shell脚本,但我们语言习惯,shell编程通常就指shell脚本编程,不是指开发shell自身。
Shell 编程需要有有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器。
Bash(Bourne Again Shell) 是大多数Linux 系统默认的 Shell。
shell脚本演示
新建一个文件 test.sh(扩展名并不影响脚本执行,见名知意就好)
[root@localhost /]# mkdir demo
[root@localhost /]# cd /demo
[root@localhost demo]# touch test.sh
[root@localhost demo]# vi test.sh
用 vi/vim 命令创建文件,输入以下内容并保存退出
#!/bin/bash
echo "Everything will be ok"
:wq
#!标记 :一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo命令 :直接输出内容。
运行 Shell 脚本:
1、作为可执行程序
将文件保存为 test.sh,并 cd 到相应目录:
[root@localhost demo]# chmod +x ./test.sh
[root@localhost demo]# ./test.sh
Everything will be ok
以我们的test.sh文件为例,直接写 test.sh是会找不到命令的,linux 系统会去 PATH 里寻找为 test.sh 的文件,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,我们的工作目录通常不在 PATH 里,./test.sh 向系统指明就在当前目录找。
当前在shell脚本所在文件夹中,可任选以下三种命令的一种运行脚本:
sh test.sh
bash test.sh
./test.sh
若不在shell脚本所在文件夹下,可用加绝对路径的命令:
/home/data/test.sh
如果刚创建时用./或者绝对路径执行不了的时候,可能是因为权限不够,可以如上述示例中先用用chmod命令来给shell文件授权。
2、作为解释器参数
直接运行解释器,其参数就是 shell 脚本的文件名:
[root@localhost demo]# /bin/sh test.sh
Everything will be ok
Shell 变量
命名规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头;
- 中间不能有空格,可以使用下划线 _;
- 不能使用标点符号;
- 不能使用bash里的关键字(可借助help命令查看);
- 变量名不加美元符号(除PHP变量);
赋值如:
the_name="mre.com"
使用变量
变量可以被读取和修改。
使用已定义的变量,只要在变量名前面加美元符号($)即可,如:
the_name="mre.com"
echo $the_name
echo ${the_name}
the_name="ming"
echo ${the_name}
花括号加不加效果都是一样的。加花括号是为了帮助解释器识别变量的边界。建议养成给变量加花括号的习惯.
已定义的变量可以被重新定义。但是注意第二次赋值的时候,不要在变量前加美元符号,使用变量的时候才加美元符号。
只读变量(readonly 变量名)
使用ready only命令可以将变量定义为只读变量,只读变量的值,不能被改变,只能进行读取。
[root@localhost ~]# cd demo
[root@localhost demo]# vi test.sh
我们在demo文件夹下的test.sh文件内做vi编辑,添加如下内容:
#!/bin/bash
myName="mre"
readonly myName
myName="mmm"
:wq保存并退出后,我们运行脚本,得如下结果:
[root@localhost demo]# sh test.sh
test.sh:行4: myName: 只读变量
执行中无法做二次赋值代码报错。
删除变量(unset 变量名)
使用unset命令可以删除变量。
变量被删除后,不能再次使用。unset命令不能删除只读变量。
示例:
#!/bin/sh
myName="mre"
unset myName
echo $myName
运行文件,由于变量被删除,没有任何输出:
[root@localhost demo]# sh test.sh
运行shell时会同时存在三种变量
- 局部变量:在脚本或命令中定义仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 环境变量:所有的程序包括shell启动的程序都能访问环境变量,有些程序需要环境变量来保证自己的正常运行,必要时shell脚本也可以定义环境变量。
- shell变量:是由shell程序设置的特殊变量,shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证shell的正常运行。
Shell 字符串
数字和字符串是shell编程中最常用的数据类型。
字符串可以用单引号也可以用双引号也可以不用引号。
单引号字符串:
str='this is a string'
特点:
任何字符都会原样输出,字符串内的变量是无效的。
字串中不能出现任何一个单引号,对单引号使用转义符号也不行,但可以成对出现,用来拼接字符串。
双引号字符串:
my_name="mre"
str="Everything be ok! \"$my_name\" \n"
echo -e $str
输出结果:
[root@localhost demo]# sh test.sh
Everything be ok! "mre"
特点:
可以有变量。
可以有转义字符。
拼接字符串:
双引号拼接:
my_name="mre"
greeting="hello, "$my_name" !"
greeting_1="hello, ${my_name} !"
echo $greeting $greeting_1
单引号拼接:
greeting_2='hello, '$my_name' !'
greeting_3='hello, ${my_name} !'
echo $greeting_2 $greeting_3
输出结果:
[root@localhost demo]# sh test.sh
hello, mre ! hello, mre !
hello, mre ! hello, ${my_name} !
特点:
可以有变量。
可以有转义字符。
获取字符串长度
str="abcd"
echo ${#str} # 输出str长度,即 4
变量为字符串时,${#str} 等价于 ${#str[0]},
str="abcd"
echo ${#str[0]}
获取字符串长度
第一个字符的索引值为 0。
str="abcdefg"
echo ${str:1:4} # 输出bcde
查找子字符串
查找字符所在位置,位置是从1开始计算的
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
注意`` 是反引号,而不是单引号
Shell 数组
Bash支持一维数组,不支持多维数组,并且不限定数组的大小。
数组元素的下标由0开始编号,获取数组中元素要用下标,下标可以是整数或算术表达式值,且应该在大于等于零。
定义数组
Shell 中用括号来表示数组,数组元素用空格符号分割,如:
array=(0 1 2 3)
可以通过下标单独定义数组的各个元素:
array[0]=11
array[1]=12
array[2]=23
读取数组
以{数组名[下标]}格式读取,如:
value=${array[2]}
使用 @ 符号可以获取数组中的所有元素,如:
echo ${array[@]}
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,如:
取得数组元素的个数
length=${#array[@]} # 等同于length=${#array[*]}
若数组单个元素有长度,也可获取
length=${#array_name[n]}
Shell 注释
单行注释:以 # 开头
多行注释:
:<<EOF
注释内容...
EOF
: 是一个空命令,用于执行后面的 Here 文档,<<‘EOF’ 表示开启 Here 文档,COMMENT 是 Here 文档的标识符,在这两个标识符之间的内容都会被视为注释,不会被执行。
示例:
: <<'COMMENT'
注释内容...
COMMENT
:<<'
注释内容...
'
:<<!
注释内容...
!
以上三种都可以,还可以使用: '注释内容’格式:
:'
注释内容...
'
Shell传参
执行shell脚本时,可以向脚本内传递参数,脚本内传参位置的传参格式为¥n。
n代表数字,代表执行传入的第几个参数
[root@localhost ~]# cd /demo
[root@localhost demo]# vi test.sh
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
执行脚本:
[root@localhost demo]# ./test.sh 1 2 3
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
使用特殊字符来处理参数:
特殊字符处理参数 | 含义 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
“$*” | 以"$1 $2 … $n"的形式显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,以一个单字符串显示所有向脚本传递的参数 |
“$@” | 与"$*“不完全相同,以”$1"“$2”…的形式显示所有向脚本传递的参数 |
$- | 显示Shell使用的当前选项,与set命令功能相同 |
$? | 显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误 |
将我们的文件添加编辑为如下内容: |
[root@localhost ~]# cd /demo
[root@localhost demo]# vi test.sh
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
echo "以一个字符串显示我们传递的所有参数:$*";
执行脚本:
[root@localhost demo]# ./test.sh 1 2 3
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
以一个字符串显示我们传递的所有参数:1 2 3
测试" ∗ " 与 " *"与" ∗"与"@"的不同显示效果:
[root@localhost demo]# touch test1.sh
[root@localhost demo]# touch test2.sh
[root@localhost demo]# vi test1.sh
for i in "$*"; do
echo $i
done
[root@localhost demo]# vi test2.sh
for i in "$@"; do
echo $i
done
分别执行脚本:
[root@localhost demo]# ./test1.sh 1 2 3
-bash: ./test1.sh: 权限不够
[root@localhost demo]# chmod +x test1.sh
[root@localhost demo]# vi test1.sh
[root@localhost demo]# ./test1.sh 1 2 3
1 2 3
[root@localhost demo]# ./test2.sh 1 2 3
-bash: ./test2.sh: 权限不够
[root@localhost demo]# chmod +x test2.sh
[root@localhost demo]# ./test2.sh 1 2 3
1
2
3
以上执行两个脚本可见两种处理参数的区别。
刚创建的文件会有权限问题,前文有解决方法,依然执行命令改变权限即可
Shell数组
数组中可以存放多个不同类型的值,Bash Shell 只支持一维数组,不支持多维数组。
不需要定义数组大小,元素下标由从0 开始。
定义数组:
数组名=(value1 value2 … valuen)
[root@localhost demo]# vi test.sh
my_array=(1 A "yyx")
echo "第一个元素为: ${my_array[0]}"
echo "第二个元素为: ${my_array[1]}"
echo "第三个元素为: ${my_array[2]}"
[root@localhost demo]# chmod +x test.sh
[root@localhost demo]# ./test.sh
第一个元素为: 1
第二个元素为: A
第三个元素为: yyx
关联数组
可以将任意的字符串、或者整数作为下标来关联数组进而访问数组元素。
语法:declare -A array_name
以下两种关联数组的方式是一样的
[root@localhost demo]# vi test.sh
#创建一个关联数组 site,并创建不同的键值
declare -A array1=(["a"]=1 ["b"]="wjx")
#先声明一个关联数组,然后再设置键和值,效果相同
declare -A array2
array2["a"]=1
array2["b"]="wjx"
echo "array1第二个元素${array1["b"]}"
echo "array2第二个元素${array2["b"]}"
执行结果:
[root@localhost demo]# ./test.sh
array1第二个元素wjx
array2第二个元素wjx
获取数组中的所有元素
使用@ 或 * ,都可以获取数组中的所有元素。如:
[root@localhost demo]# vi test.sh
array1[0]=A
array1[1]=B
array1[2]=C
declare -A array2
array2["a"]=1
array2["b"]=2
array2["c"]=3
echo "array1数组的元素为: ${array1[*]}"
echo "array1数组的元素为: ${array1[@]}"
echo "array2数组的元素为: ${array2[*]}"
echo "array2数组的元素为: ${array2[@]}"
执行脚本:
[root@localhost demo]# ./test.sh
array1数组的元素为: A B C
array1数组的元素为: A B C
array2数组的元素为: 1 2 3
array2数组的元素为: 1 2 3
在数组前加一个感叹号 ! 可以获取数组的所有元素对应的键,如:
[root@localhost demo]# vi test.sh
array1[0]=A
array1[1]=B
array1[2]=C
declare -A array2
array2["a"]=1
array2["b"]=2
array2["c"]=3
echo "数组的键为: ${!array1[*]}"
echo "数组的键为: ${!array1[@]}"
echo "数组的键为: ${!array2[*]}"
echo "数组的键为: ${!array2[@]}"
执行脚本:
[root@localhost demo]# ./test.sh
数组的键为: 0 1 2
数组的键为: 0 1 2
数组的键为: a b c
数组的键为: a b c
获取数组的长度
与获取字符串长度的方法相同,如:
echo "数组元素个数为: ${#array1[*]}"
echo "数组元素个数为: ${#array1[@]}"
echo "数组元素个数为: ${#array2[*]}"
echo "数组元素个数为: ${#array2[@]}"
执行脚本:
[root@localhost demo]# ./test.sh
数组元素个数为: 3
数组元素个数为: 3
数组元素个数为: 3
数组元素个数为: 3
Shell基本运算符
算数运算符
变量 a 为 10,变量 b 为 20为例:
运算符 | 示例 |
---|---|
+ | 实现参数相加。expr $a + $b 得30 |
- | 实现参数相减。expr $b - $a 得10 |
* | 实现参数相乘。expr $b \* $a 得200 |
/ | 实现参数相除。expr $b / $a 得2 |
% | 实现取余数。expr $b % $a 得0 |
= | 实现参数的赋值。a=$b ,a为20 |
== | 比较参数的值(相同返回 true;不同返回 false)。[ $a == $b ] 得 false |
!= | 比较参数的值(相同返回 false;不同返回 true)。[ $a == $b ] 得 true |
其中需注意:
-
表达式和运算符之间要有空格,如 2+2 是错的,必须写成 2 + 2
-
乘号(*)前边必须加反斜杠()才能实现乘法运算
-
条件表达式要注意放在方括号之间,并且也一定要有空格,如: [ a = = a== a==b] 是错的,必须写成 [ $a == $b ]
代码示例:
[root@localhost demo]# vi test.sh
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $b - $a`
echo "b - a : $val"
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
执行脚本:
[root@localhost demo]# ./test.sh
a + b : 30
b - a : 10
a * b : 200
b / a : 2
b % a : 0
关系运算符
变量 a 为 10,变量 b 为 20为例:
运算符 | 示例 |
---|---|
-eq | 若参数相等返回 true;不同返回 false。[ $a -eq $b ] 得false |
-ne | 若参数相同返回 false;不同返回 true。[ $a -ne $b ] 得true |
-gt | 若左边参数大于右边参数返回 true;否则返回 false。[ $a -gt $b ] 得false |
-lt | 若左边参数小于右边参数返回 true;否则返回 false。[ $a -lt $b ] 得true |
-ge | 若左边参数大于等于右边参数返回 true;否则返回 false。[ $a -ge $b ] 得 false |
-le | 若左边参数小于等于右边参数返回 true;否则返回 false。[ $a -le $b ] 得 true |
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
代码示例:
[root@localhost demo]# vi test.sh
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
执行脚本:
[root@localhost demo]# ./test.sh
10 -eq 20: a 不等于 b
10 -ne 20: a 不等于 b
10 -gt 20: a 不大于 b
10 -lt 20: a 小于 b
10 -ge 20: a 小于 b
10 -le 20: a 小于或等于 b
布尔运算符
变量 a 为 10,变量 b 为 20为例:
运算符 | 示例 |
---|---|
! | 非运算,表达式为 true 则返回 false,为false返回 true。[ ! false ] 返回 true。 |
-o | 或运算,左右任一表达式为 true 则返回true,否则返回 false。[ $a -lt 20 -o $b -gt 20 ] 得true |
-a | 与运算,左右任一表达式为 true 才返回true,否则返回 false。[ $a -lt 20 -o $b -gt 20 ] 得false |
代码示例:
[root@localhost demo]# vi test.sh
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
执行脚本:
[root@localhost demo]# ./test.sh
10 != 20 : a 不等于 b
10 小于 100 且 20 大于 15 : 返回 true
10 小于 100 或 20 大于 100 : 返回 true
10 小于 5 或 20 大于 100 : 返回 false
逻辑运算符
变量 a 为 10,变量 b 为 20为例:
运算符 | 示例 |
---|---|
&& | 逻辑与,[[ $a -lt 20 && $b -gt 10 ]] 得 false |
|| | 逻辑或,[[ $a -lt 20 && $b -gt 10 ]] 得true |
代码示例:
[root@localhost demo]# vi test.sh
a=10
b=20
if [[ $a -lt 20 && $b -gt 10 ]]
then
echo "true"
else
echo "false"
fi
if [[ $a -lt 20 && $b -gt 10 ]]
then
echo "true"
else
echo "false"
fi
执行脚本:
[root@localhost demo]# ./test.sh
false
true
Shell命令
echo命令
用于字符串的输出。
语法:echo 字符串
- 显示字符串
echo "Everything will be ok"
双引号可以省略,即等效于
echo Everything will be ok
执行显示:
Everything will be ok
还可以结合转义字符:
echo "\"Everything will be ok\""
双引号也可以省略,即等效于
echo \"Everything will be ok\"
执行显示:
"Everything will be ok"
- 显示换行或不换行
语法:echo -e 含换行或不换行转义字符的字符串。-e表示开始转义
转义字符 | 显示效果 |
---|---|
\n | 换行 |
\c | 不换行 |
[root@localhost demo]# vi test.sh
echo -e "Everything will be ok \n"
echo -e "Everything will be ok \c"
执行显示:
[root@localhost demo]# ./test.sh
Everything will be ok
Everything will be ok
- 显示变量
[root@localhost demo]# vi test.sh
read name
echo "$name ,everything will be ok"
read命令:标准输入,接收输入信息赋给变量name
[root@localhost demo]# ./test.sh
mre
mre ,everything will be ok
- 显示结果定向至文件
[root@localhost demo]# touch test1.txt
[root@localhost demo]# vi test.sh
echo "Everything will be ok " >test1.txt
执行脚本:
[root@localhost demo]# ./test.sh
[root@localhost demo]# cat test1.txt
Everything will be ok
接收文件内原本有内容的话会被覆盖掉
- 原样输出字符串,不进行转义或取变量
用单引号包裹显示内容即可:
echo '$name\"'
执行显示:
$name\"
- 显示其他命令的执行结果
用反引号包裹显示内容即可:
[root@localhost demo]# echo `date`
2023年 10月 14日 星期六 11:51:47 CST
[root@localhost demo]# echo `cat test1.txt`
Everything will be ok
即可显示其他Linux命令的执行结果。
printf 命令
也是一种输出命令。
- printf 命令是模仿 C 语言里的 printf() 程序。
- printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
- printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
语法:printf 格式化控制 [参数1 参数2 … 参数n]
格式化控制部分可用双引号包裹,可用单引号包裹,也可不用单引号包裹。
格式替代符 | 含义 |
---|---|
%s | 输出一个字符串,若无参数则用NULL代替 |
%d | 整型输出,若无参数则用0代替 |
%c | 输出一个字符 |
%f | 输出实数,以小数形式输出(默认输出小数点后六位) |
代码示例:
printf "%-8s %-8s %-2s\n" 姓名 性别 体重
printf "%-8s %-8s %-3.2f\n" 刘宣 男 59.1212
printf "%-8s %-8s %-3.2f\n" 赵青 男 62.1123
执行脚本:
姓名 性别 体重
刘宣 男 59.12
赵青 男 62.11
其中:
- %-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),字符内容会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
- %-3.2f 为格式化为小数,其中 .2 指保留2位小数。
若参数比格式指定的参数个数多,则格式化控制会被重用,多出的参数仍然会按照该格式输出。如:
printf "%s %s %s\n" a b c d e f g h i j
执行:
a b c
d e f
g h i
j
test命令
test 命令用于检查某个条件是否成立,支持数值、字符和文件。
语法:test 变量1 参数 变量2
数值检查
参数 | 说明 |
---|---|
-eq | 等于则为true |
-ne | 不等于则为true |
-gt | 大于则为true |
-ge | 大于等于则为true |
-lt | 小于则为true |
-le | 小于等于则为true |
代码示例:
n1=12
n2=12
if test $[n1] -eq $[n2]
then
echo '相等'
else
echo '不相等'
fi
执行显示:
相等
代码中的 [] 执行基本的算数运算,如:
n1=12
n2=12
if test $[n1] -eq $[n1+n2]
then
echo '相等'
else
echo '不相等'
fi
输出显示:
不相等
字符串检查
参数 | 说明 |
---|---|
= | 等于则为true |
!= | 不等于则为true |
-z 字符串 | 字符串的长度为零则为true |
-n 字符串 | 字符串的长度不为零则为true |
字符串检查区分大小写
s1="mre"
s2="Mre"
if test $s1 = $s2
then
echo '相等'
else
echo '不相等'
fi
输出显示:
不相等
文件检查
参数 | 说明 |
---|---|
-e | 文件存在则为true |
-r | 文件存在且可读则为true |
-w | 文件存在且可写则为true |
-x | 文件存在且可执行则为true |
-s | 文件存在且至少有一个字符则为true |
-d | 文件存在且为目录则为true |
-f | 文件存在且为普通文件则为true |
-c | 文件存在且为字符型特殊文件则为true |
-b | 文件存在且为块特殊文件则为true |
代码示例: |
if test -e ./test.sh
then
echo '文件已存在'
else
echo '文件不存在'
fi
执行输出:
文件已存在
还可以使用与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来。
其优先级为: ! 最高, -a 次之, -o 最低。
如:
test -e ./test.sh -o -e ./test.txt
结果为真
Shell流程控制
if
语法格式:
1.多行:
if condition
then
command1
command2
...
commandN
fi
2.单行
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
fi 就是 if 倒过来拼写,一对if-fi是一个if流程体。
if else
语法格式:
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
语法格式:
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
condition1可以用中括号包裹,判断语句中大于使用 -gt,小于使用 -lt:
if [ "$a" -gt "$b" ]; then
...
fi
condition1也可以用双重小括号包裹,判断语句中大于和小于使用 > 和 <即可:
if (( a > b )); then
...
fi
两种判断方式随意使用
脚本演示:
[root@localhost demo]# vi test.sh
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif (( a > b ))
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "输入错误"
fi
执行显示:
[root@localhost demo]# ./test.sh
a 小于 b
if else 语句经常与 test 命令结合使用,如:
n1=$[2*24]
n2=$[12+12]
if test $[n1] -eq $[n2]
then
echo '相等'
else
echo '不相等'
fi
执行显示:
[root@localhost demo]# ./test.sh
不相等
for 循环
语法格式:
1.多行:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
2.单行:
for var in item1 item2 ... itemN; do command1; command2… done;
其中:
- command命令部分可为任何有效的 shell 命令和语句。
- in 列表可选的,并且可以为数字、字符串和文件名。
- 如果不用in 列表,for循环即使用命令行的位置参数。
in 列表为字符串:
[root@localhost demo]# vi test.sh
for str in Everything will be ok
do
echo $str
done
执行显示:
[root@localhost demo]# ./test.sh
Everything
will
be
ok
while 循环
语法格式:
1.多行:
while condition
do
command
done
脚本演示:
[root@localhost demo]# vi test.sh
num=1
while(( $num<=5 ))
do
echo $num
let "num++"
done
let 命令用于执行一个或多个表达式,变量计算中不需要加上 $ 即可表示变量。
执行演示:
[root@localhost demo]# ./test.sh
1
2
3
4
5
死循环:
while :
do
command
done
或者
while true
do
command
done
或者
for (( ; ; ))
until 循环
语法格式:
until condition
do
command
done
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
- until 循环执行一系列命令直至条件为 true 时停止
- until 循环与 while 循环在处理方式上刚好相反
- 一般 while 循环优于 until 循环,极少数情况下,until 循环更加有用
脚本演示:
a=0
until [ $a -ge 5 ]
do
echo $a
a=`expr $a + 1`
done
执行显示:
[root@localhost demo]# ./test.sh
0
1
2
3
4
case … esac
语法格式:
case 值 in
值或模式1)
...
;;
值或模式2)
...
;;
esac
case … esac 为多选择语句,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
case 语句支持匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。
脚本演示:
a=1
case $a in
1) echo '1'
;;
*) echo 'error'
;;
esac
执行显示:
[root@localhost demo]# ./test.sh
1
Shell函数
函数定义格式:
[ function ] funname ()
{
...
[return int;]
}
funname
- function关键字可加可不加
- 一对funname规定了函数开始和结束的范围
- 函数返回值在调用该函数后通过 $? 来获得
- 所有函数在使用前必须定义,所以Shell中必须将函数放在脚本开始部分。shell解释器首次发现函数时,它才可以使用。之后调用函数仅使用其函数名即可。
脚本演示:
[root@localhost demo]# vi test.sh
numAdd(){
read a
read b
return $(($a+$b))
}
numAdd
echo "两个数字之和为 $? "
执行结果:
[root@localhost demo]# ./test.sh
12
24
两个数字之和为 36
向函数传参:
调用函数时如果向其传递参数,在函数体内部通过 $n 的形式来获取参数的值。如$1表示第一个参数。
脚本演示:
[root@localhost demo]# vi test.sh
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
fun(){
echo "第一个参数: $1 "
echo "第二个参数: $2 "
echo "第十个参数: $10 "
echo "第十个参数: ${10} "
echo "第十一个参数: ${11} "
echo "参数总数: $# 个!"
echo "传入的参数列表 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 10 11
执行结果:
[root@localhost demo]# ./test.sh
12
24
两个数字之和为 36
当n>=10时,需要使用${n}来获取参数。如上例中 10 不能获取第十个参数,获取第十个参数需要 10 不能获取第十个参数,获取第十个参数需要 10不能获取第十个参数,获取第十个参数需要{10}。
参数处理 | 效果说明 |
---|---|
$# | 传入到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传入的参数 |
$$ | 获取脚本运行的当前进程ID号 |
$@ | 与$*相同,但是使用时要加引号,并在引号中返回每个参数。 |
$! | 获取后台运行的最后一个进程的ID号 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表示有错误。 |
Shell 输入/输出重定向(今日补充)
一个命令通常从一个叫标准输入的地方读取输入,默认情况下,是我们的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,也是我们的终端。
重定向命令列表:
重定向命令 | 效果说明 |
---|---|
command > file | 将输出重定向到 file |
command < file | 将输入重定向到 file |
command >> file | 将输出以追加的方式重定向到 file |
n > file | 将文件描述符为 n 的文件重定向到 file |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file |
n >& m | 将输出文件 m 和 n 合并 |
n <& m | 将输出文件 m 和 n 合并 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
关于n文件描述符:
0 ——标准输入
1 ——标准输出
2 ——标准错误输出
- command > file 输出重定向(内容覆盖)
重定向一般通过在命令间插入指定符号来实现,如:
[root@localhost test2]# date > a.txt
查看文件:
[root@localhost test2]# cat a.txt
2023年 10月 19日 星期四 01:01:08 CST
- command >> file 输出重定向(内容覆盖)
使用 >> 可以实现追加到文件末尾,如:
[root@localhost test2]# echo "Everything will be ok" >> a.txt
查看文件:
[root@localhost test2]# cat a.txt
2023年 10月 19日 星期四 01:01:08 CST
Everything will be ok
- command < file 输出重定向(内容覆盖)
需要从键盘获取输入的命令会转移到文件读取内容,如:
[root@localhost test2]# wc -l < a.txt
- command1 < infile > outfile 同时替换输入和输出(内容覆盖)
从文件infile读取内容,然后将输出写入到outfile中
每个 Linux 命令运行时都会打开三个文件:
(1)标准输入文件(stdin):stdin的文件描述符为0
(2)标准输出文件(stdout):stdout 的文件描述符为1
(3)标准错误文件(stderr):stderr的文件描述符为2
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
- Here Document
Here Document 是 一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。会将一对 delimiter 之间的内容document作为输入传递给 command。
语法格式:
command << delimiter
document
delimiter
其中:
- 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
- 开始的delimiter前后的空格会被忽略掉
如:
[root@localhost demo]# vi test.sh
cat << EOF
Everything
will
be
ok
EOF
执行脚本:
[root@localhost demo]# ./test.sh
Everything
will
be
ok
- /dev/null 文件
可以实现执行某个命令,也不在屏幕上显示输出结果。
语法格式:
command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃。如果尝试从该文件读取内容,结果是什么也读不到。
因此 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。如:
command > /dev/null 2>&1
可以实现屏蔽 stdout 和 stderr。
注意 2 和 > 之间不可以有空格,2> 两个符号一体的时候才表示错误输出。