Linux 系统中一切皆文件。
转义字符\的作用就是将具备特殊含义的字符转义声明为普通字符使用,同理\表示将自身转义为普通反斜杠字符。
简单理解:xxx文件与 xxx.txt或是 xxx.sh 是没有本质区别的
/Home:不同用户目录操作空间的主目录。
一般都是基于/home/user/下进行命令操作。
1.绝对路径与相对路径 我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。
其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们。
绝对路径: 路径的写法,由根目录 / 写起,例如: /usr/share/doc 这个目录。
相对路径: 路径的写法,不是由 / 写起,例如由 /usr/share/doc 要到 /usr/share/man 底下时,可以写成: cd ../man 这就是相对路径的写法。
只要不是从/开始的都是相对路径,默认相对位置为当前路径。
自定义命令
Linux环境可以支持软件自定义命令,例如安装的对应软件都可以在terminal通过其对应的命令触发实现操作:docker,git。
原生:shell命令->解释器->系统调用->Linux内核
软件:软件自定义命令->对应可执行文件->系统调用->Linux内核
linux自定义命令
/bin目录中包含可执行命令,可以找一下对应的软件自定义命令
或者根据PATH变量中指定的存储可执行命令的路径,一一查询对应的软件自定义命令。
which command就可以查询PATH变量全部存储路径中的可执行文件命令。
读写操作
写操作时若没有对应文件则会直接自动新建文件并写入,读操作不行若没有对应文件那就是没有,无法读取,无法解决。
实例:安装软件时都是自建软件名文件夹然后安装写入。
command -options
command的-后面可以接多个option
例如:ls -lrt,rm -rf等等
Sudo为临时使用Linux的root权限
参考博客
注意: Linux中 管理员账户是 #, 普通账户是 $
Linux命令管理文件的精髓:文件管理命令都可以批量操作文件(灵活利用通配符*)
所有文件操作命令都可以和路径结合食用。
操作内容用正则,操作文件名用通配符
例如:
rm *.txt:删除所有txt类型文件
rm dir_* -r:删除所有dir_开头的文件夹
mv *.txt dir:移动所有txt文件到dir文件夹下
ls *.sh:列出当前目录下所有sh文件
rm/cat/ls ABC*:查看/展示/删除ABC前缀的文件
cat *.sh > all.sh:将当前目录下的全部sh文件内容读取并重定向stdout输出为all.sh文件
grep xxx ./*.filetype:将path下的全部filetype文件内容进行查询匹配逐行输出=》文件名:匹配列
rm,mkdir,cp等操作文件夹要加-r
~======/home/uesr_name( 当前用户目录的绝对路径)
linux 中的“~”和“/”
pwd命令可以显示当前工作目录的绝对路径。其中pwd是print working directory 的缩写。
Linux内核通过进程对任务进行管理,在终端界面启动一个进程后,使用Ctrl+Z和Ctrl+C都可以用退出进程,返回到终端界面。区别在于:
如果将终端比作前台,终端背后所看不到的系统比作后台,Ctrl+Z将进程暂停并挂在了后台,使用户可以继续查看和操作前台终端。
(1) ctrl c: 取消命令终止进程,并且换行
(2) ctrl u: 清空本行命令
(3) tab键: 可以补全命令和文件名,如果补全不了快速按两下tab键,可以显示备选选项
history:显示历史命令
(4) ls: 列出当前目录下所有文件,蓝色的是文件夹,白色的是普通文件,绿色的是可执行文件
所有被隐藏的文件都是以.开头的
ls *.filetype:列出当前目录下所有filetype类型的文件。
ls -lrt 表示 按修改时间 倒序 列出当前工作目录下的所有文件的详细信息
作用:目录新增文件时,根据时间排序快速查找对应新增文件,最底的就是新增文件。
ls -lrth 多列出了各个文件大小
ll既可以查看该目录文件还可以查看对应权限
find xxx:查看当前目录下该xxx文件的文件以及结构
(5) pwd: 显示当前绝对路径(change directary:进出某目录都只能用cd)
(6) cd XXX: 进入XXX目录下,
(7) cp XXX YYY: 将XXX文件复制到YYY,XXX和YYY可以是一个路径,比如…/dir_c/a.txt,表示上层目录下的dir_c文件夹下的文件a.txt
cp=复制+粘贴+重命名
cp 文件夹A 文件夹B -r:将A文件夹复制到B文件夹中。
cp 文件夹A ./重命名a -r
mv 文件A 文件夹B:类似剪切功能
若mv 文件A 文件a:实现重命名功能
注意:
mv重命名是修改原文件。
cp=复制+粘贴+重命名,原文件不变,复制产生新命名文件。
cp,mv 支持线程处理,指令后加入参 --threads 线程数,例如 cp --threads 10 -r dir1 dir2
(8) mkdir XXX: 创建目录文件夹XXX
mkdir qlu\ gcl:文件夹名为qlu gcl
(9) rm XXX: 删除普通文件; rm XXX -r: 删除文件夹
rm * -r:删除当前目录下的所有文件夹和普通文件以及隐藏文件
rm *:删除当前目录下的所有普通文件
rm XXX -rf:强制删除XXX文件夹
(10) mv XXX YYY: 将XXX文件移动到YYY,和cp命令一样,XXX和YYY可以是一个路径;重命名也是用这个命令
(11) touch XXX: 创建一个文件
(12) cat XXX: 展示文件XXX中的内容
(13) 复制文本
windows/Linux下:Ctrl + insert,Mac下:command + c
(14) 粘贴文本
windows/Linux下:Shift + insert,Mac下:command + v
(15) tree查看当前目录文件的树形结构
同理:
此处的命令是将ls -lrt挂载到服务执行并将执行结果重定向输出到test.txt文件中
将command命令挂载到服务器端执行,并且在默认情况下(非重定向时:无>),会将命令运行结果输出一个名叫 nohup.out 的后台进程运行日志文件到当前目录下。
一般情况下配合tail食用,follow跟踪观察挂载到服务器命令执行结果。
tail -f nohup.out
ctr + c终止跟踪,退出界面。
或者
ps -ef | grep command
(1) 同一窗口分屏。
(2) 允许断开Terminal连接后,继续运行进程。(将任务挂到云端服务器执行不受终端的开关影响)
当突然断电断网的时候tmux任务不受终端影响。
tmux a(attach):进入上次tmux窗口继续运行命令。
session:登录操作服务器的会话
window:terminal窗口
pane:teiminal窗口的分割单位
shell:命令交互程序
一个tmux可以包含多个session,一个session可以包含多个window,一个window可以包含多个pane。
实例:
tmux:
session 0:
window 0:
pane 0
pane 1
pane 2
...
window 1
window 2
...
session 1
session 2
...
Ctr+a s
查看tmux构建的全部session
筛选进入想进入的session
tmux ls
清空所有tmux构建的session
tmux kill-server
清除指定的tmux构建的session
tmux kill-window -t session序号
(1) tmux:新建一个session,其中包含一个window,window中包含一个pane,pane里打开了一个shell对话框。
(2) 按下Ctrl + a后手指松开,然后按%:将当前pane左右平分成两个pane。
(3) 按下Ctrl + a后手指松开,然后按"(注意是双引号"):将当前pane上下平分成两个pane。
(4) Ctrl + d:关闭当前pane;如果当前window的所有pane均已关闭,则自动关闭window;如果当前session的所有window均已关闭,则自动关闭session。
(5) 鼠标点击可以选pane。
(6) 按下ctrl + a后手指松开,然后按方向键:选择相邻的pane。
(7) 鼠标拖动pane之间的分割线,可以调整分割线的位置。
(8) 按住ctrl + a的同时按方向键,可以调整pane之间分割线的位置。
(9) 按下ctrl + a后手指松开,然后按z:将当前pane全屏/取消全屏。
(10) 退出tmux:按下ctrl + a后手指松开,然后按d:挂起当前session。
(11) 重新进入tmux:tmux a(attach):打开之前挂起的session。
(12) 按下ctrl + a后手指松开,然后按s:选择其它session。
方向键 —— 上:选择上一项 session/window/pane
方向键 —— 下:选择下一项 session/window/pane
方向键 —— 右:展开当前项 session/window
方向键 —— 左:闭合当前项 session/window
(13) 按下Ctrl + a后手指松开,然后按c(create):在当前session中创建一个新的window。
(14) 按下Ctrl + a后手指松开,然后按w:选择其他window,操作方法与(12)完全相同。(session目录展开式)
(15) 按下Ctrl + a后手指松开,然后按PageUp:翻阅当前pane内的内容。
(16) 鼠标滚轮:翻阅当前pane内的内容。
(17) 在tmux中选中文本时,需要按住shift键。(仅支持Windows和Linux,不支持Mac,不过该操作并不是必须的,因此影响不大)
(18) tmux中复制/粘贴文本的通用方式:
(1) 按下Ctrl + a后松开手指,然后按[
(2) 用鼠标选中文本,被选中的文本会被自动复制到tmux的剪贴板
(3) 按下Ctrl + a后松开手指,然后按],会将剪贴板中的内容粘贴到光标处
vi 和vim 的区别
vim比vi功能更强大,但是vi可以用于docker容器的简单Linux终端环境中文本/脚本编辑。
vim常用操作
1、i:进入插入模式。从目前光标处插入。
2、I(大写i):进入插入模式。从目前所在行的第一个非空格符处开始插入。
3、a:进入插入模式。从目前光标所在处的下一个字符处开始插入。
4、A:进入插入模式。从光标所在行的最后一个字符处开始插入。
5、o:进入插入模式。从目前光标处所在的下一行处插入新的一行。
6、O:进入插入模式。从目前光标所在处的上一行插入新的一行。
7、r:进入替换模式。替换光标所在处的那一个字符一次。
8、R:进入替换模式。一直替换光标所在处的字符,直到按下Esc键为止。
9、U:回退,撤销上一步操作。
10、Esc:退出编辑模式返回到一般模式。
二、从一般模式切换到命令行模式
上面的命令只是在vi编辑命令中使用
首先使用esc(键退出)->:(符号输入)->wq(保存退出)
:wq(保存编辑操作退出)
:wq!(保存编辑强制退出
1、:w:把编辑好的数据写入到硬盘文件中。
2、:w!:当文件属性为“只读”时强制写入该文件。具体能不能写入还要看该文件的文件权限。
3、:q:离开vi。
4、:q!:如果修改过文件但不需要存储,使用“!”强制离开不保存文件。
5、:wq:保存后离开。
6、:wq!:强制保存后离开。
7、:w[filename]:将编辑的数据保存成以filename命名的文件,相当于另存为文件。
8、:r[filename]:在编辑的数据中读另一个文件的内容,即将filename文件的内容加载到光标所在行的后面。
9、:num1,num2w[filename]:将num1到num2的内容保存成文件名filename的文件。
10:、:set nu:显示行号,设置完成后将会在每一行的前缀显示行号。
11、:set nonu:取消行号。
(1) 命令行模式下的文本编辑器。
(2) 根据文件扩展名自动判别编程语言。支持代码缩进、代码高亮等功能。
(3) 使用方式:vim filename.文件类型
如果已有该文件,则打开它。
如果没有该文件,则打开个一个新的文件,并命名为filename
(1) 一般命令模式
默认模式。命令输入方式:类似于打游戏放技能,按不同字符,即可进行不同操作。可以复制、粘贴、删除文本等。
(2) 编辑模式
在一般命令模式里按下i,会进入编辑模式。
按下ESC会退出编辑模式,返回到一般命令模式。
(3) 命令行模式
在一般命令模式里按下:/?三个字母中的任意一个,会进入命令行模式。命令行在最下面。
可以查找、替换、保存、退出、配置编辑器等。
按下ESC会退出命令行模式,返回到一般命令模式。
组合键:
ggdG:文本全删
%s/source_pattern/target_pattern/g:将全文source_pattern替换为target_pattern
(1) i:进入编辑模式
(2) ESC:进入一般命令模式
(3) h 或 左箭头键:光标向左移动一个字符
(4) j 或 向下箭头:光标向下移动一个字符
(5) k 或 向上箭头:光标向上移动一个字符
(6) l 或 向右箭头:光标向右移动一个字符
(7) n:n表示数字,按下数字后再按空格,光标会向右移动这一行的n个字符
(8) 0 或 功能键[Home]:光标移动到本行开头
(9) $ 或 功能键[End]:光标移动到本行末尾
(10) G:光标移动到最后一行
(11) :n 或 nG:n为数字,光标移动到第n行
(12) gg:光标移动到第一行,相当于1G
(13) n:n为数字,光标向下移动n行
(14) /word:向光标之下寻找第一个值为word的字符串。
(15) ?word:向光标之上寻找第一个值为word的字符串。
(16) n:重复前一个查找操作可与(14)(15)搭配实现连续查找
(17) N:反向(上->下)重复前一个查找操作
(18) :n1,n2s/word1/word2/g:n1与n2为数字,在第n1行与n2行之间寻找word1这个字符串,并将该字符串替换为word2
(19) :1,$s/word1/word2/g:将全文的word1替换为word2
(20) :1,$s/word1/word2/gc:将全文的word1替换为word2,且在替换前要求用户确认。
(21) v:选中文本
(22) d:删除v选中的文本
(23) dd: 删除当前行
(24) y:复制v选中的文本
(25) yy: 复制当前行
(26) p: 将复制的数据在光标的下一个位置粘贴
(27) u:撤销(类比window的ctr+z)
(28) Ctrl + r:取消撤销(类比window的ctr+shift+z)
(29) 大于号 >:将v选中的文本整体向右缩进一次
(30) 小于号 <:将v选中的文本整体向左缩进一次
(31) :w 保存
(32) :w! 强制保存
(33) :q 退出
(34) :q! 强制退出
(35) :wq 保存并退出
(36) :set paste 设置成粘贴模式,取消代码自动缩进
(37) :set nopaste 取消粘贴模式,开启代码自动缩进
(38) :set nu 显示行号
(39) :set nonu 隐藏行号
(40) gg=G:将全文代码格式化(缩进等等)
(41) :noh 关闭查找关键词高亮
(42) Ctrl + q:当vim卡死时,可以取消当前正在执行的命令
异常处理:
异常原因:不可同时使用vim打开同一个文件。不可以将写权限同时给多个用户。
每次用vim编辑文件时,会自动创建一个.filename.swp的临时文件((缓存文件)。
如果打开某个文件时,该文件的swp文件已存在(已被打开加载进缓存),则会报错。此时解决办法有两种:
(1) 找到正在打开该文件的程序,并退出
(2) 直接删掉该swp文件即可
shell脚本基础
shell脚本若需要#!则必须放在首行,若是首行是空格则不同版本下会有问题。
在#!之后,接一个路径名,这个路径名指定了一个解释脚本命令的程序。
echo (stdout/运行结果)==cout 运行结果
exitcode 0(真|正常运行) 1(假|运行出错)==return 0 1
能在terminal看见输出结果的都为stdout命令(查看命令:cat,ls等)。
万无一失:
变量运用时:${变量}
字符串常量运用时:“字符串”
第一种使用绝对路径执行
第二种使用相对路径执行,如./的方式
第三种使用 sh命令来执行 格式 sh 脚本名 不需要执行权限 -x参数(显示执行过程)
第四种使用 . (空格)脚本名称的方式执行 不需要执行权限 . a.sh
第五种使用 source 脚本名称 不需要执行权限(主要用于生效配置文件)
Terminal和bash是两回事奥,terminal是IO环境,BASH是命令解释与执行器,完全不一样
shell是我们通过命令行与操作系统沟通的语言。
shell语言不需要编译直接解释运行。
shell脚本可以直接在命令行中执行,也可以将一套逻辑组织成一个文件,方便复用。
Linux中常见的shell脚本有很多种,常见的有:
Linux系统中一般默认使用bash,所以接下来讲解bash中的语法。
文件开头需要写#! /bin/bash,指明bash为脚本解释器。
shell脚本的第一行指定脚本解释器,不过值得注意的是,当我们使用指定解释器运行脚本的时候
bash *.sh
sh *.sh
我们脚本文件中的第一行会失效,比如通过bash+文件名运行脚本的方式,这样即便我在文件中指定是sh解释器,结果依然会以bash解释器运行.
学习技巧
不要死记硬背,遇到含糊不清的地方,可以在AC Terminal里实际运行一遍。
脚本示例
新建一个test.sh文件,内容如下:
vim test.sh
#! /bin/bash
echo "Hello World!"
运行方式
作为可执行文件
acs@9e0ebfcd82d7:~$ chmod +x test.sh # 使脚本具有可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh # 当前路径下执行
Hello World! # 脚本输出
acs@9e0ebfcd82d7:~$ /home/acs/test.sh # 绝对路径下执行
Hello World! # 脚本输出
acs@9e0ebfcd82d7:~$ ~/test.sh # 家目录路径下执行
Hello World! # 脚本输出
用解释器执行
bash或sh *.sh
sh优于bash
acs@9e0ebfcd82d7:~$ bash test.sh
Hello World! # 脚本输出
单行注释
每行中#之后的内容均是注释。
# 这是一行注释
echo 'Hello World' # 这也是注释
多行注释
格式:
:<<start
end
:<<EOF
第一行注释
第二行注释
第三行注释
EOF
其中EOF可以换成其它任意字符串。例如:
:<<abc
第一行注释
第二行注释
第三行注释
abc
:<<!
第一行注释
第二行注释
第三行注释
!
linux shell脚本EOF妙用-----------向一个文件输入多行内容
定义变量,不需要加$符号,例如:
声明即定义
name1='yxc' # 单引号定义字符串
name2="yxc" # 双引号定义字符串
name3=yxc # 也可以不加引号,同样表示字符串
使用变量
使用变量,需要加上$符号,或者${}符号。花括号是可选的,主要为了帮助解释器识别变量边界。
name=yxc
echo $name # 输出yxc
echo ${name} # 输出yxc
echo ${name}acwing # 输出yxcacwing
只读变量
使用readonly或者declare可以将变量变为只读。
name=yxc
readonly name
declare -r name # 两种写法均可
name=abc # 会报错,因为此时name只读
删除变量
unset可以删除变量。
name=yxc
unset name
echo $name # 输出空行
变量类型
自定义变量(局部变量) 子进程不能访问的变量
环境变量(全局变量) 子进程可以访问的变量
自定义变量改成环境变量:
acs@9e0ebfcd82d7:~$ name=yxc # 定义变量
acs@9e0ebfcd82d7:~$ export name # 第一种方法
acs@9e0ebfcd82d7:~$ declare -x name # 第二种方法
环境变量改为自定义变量:
acs@9e0ebfcd82d7:~$ export name=yxc # 定义环境变量
acs@9e0ebfcd82d7:~$ declare +x name # 改为自定义变量
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号与双引号的区别:
name=yxc # 不用引号
echo 'hello, $name \"hh\"' # 单引号字符串,输出 hello, $name \"hh\"
echo "hello, $name \"hh\"" # 双引号字符串,输出 hello, yxc "hh"
单双引号可以相互包容并原样显示。
注意:实际应用时单包双/双包单,不可单包单,双包双,无意义。
获取字符串长度
name="yxc"
echo ${#name} # 输出3
提取子串
Shell字符串截取(非常详细)
name="hello, yxc"
echo ${name:0:5} # 提取从0开始的5个字符
如果想从字符串的左边开始计数,那么截取字符串的具体格式如下:
${string: start :length}
其中,string 是要截取的字符串,start 是起始位置(从左边开始,从 0 开始计数),length 是要截取的长度(省略的话表示直到字符串的末尾)。
文件参数变量
在执行shell脚本时,可以向脚本传递参数。$1是第一个参数,$2是第二个参数,以此类推。特殊的,$0是文件名(包含路径)。例如:
创建文件test.sh:vim test.sh
#! /bin/bash
echo "文件名:"$0
echo "第一个参数:"$1
echo "第二个参数:"$2
echo "第三个参数:"$3
echo "第四个参数:"$4
然后执行该脚本:
acs@9e0ebfcd82d7:~$ chmod +x test.sh
acs@9e0ebfcd82d7:~$ ./test.sh 1 2 3 4
文件名:./test.sh
第一个参数:1
第二个参数:2
第三个参数:3
第四个参数:4
数组中可以存放多个不同类型的值,只支持一维数组,初始化时不需要指明数组大小。
数组下标从0开始。
定义声明
数组用小括号表示,元素之间用空格隔开。例如:
array=(1 abc "def" yxc)
也可以直接定义数组中某个元素的值:
先定义声明数组才能赋值使用数组
array[0]=1
array[1]=abc
array[2]="def"
array[3]=yxc
读取数组中某个元素的值
格式:
${array[index]}
例如:
array=(1 abc "def" yxc)
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}
echo ${array[3]}
读取整个数组
格式:
*和@表示全部的意思
${array[@]} # 第一种写法
${array[*]} # 第二种写法
例如:
array=(1 abc "def" yxc)
echo ${array[@]} # 第一种写法
echo ${array[*]} # 第二种写法
数组长度
类似于字符串
${#array[@]} # 第一种写法
${#array[*]} # 第二种写法
例如:
array=(1 abc "def" yxc)
echo ${#array[@]} # 第一种写法
echo ${#array[*]} # 第二种写法
使用变量,需要加上$符号,或者${}符号。花括号是可选的,主要为了帮助解释器识别变量边界。
expr命令用于求表达式的值,格式为:
expr 表达式
注意:expr需要配合``或者$()返回stdout运算结果。
表达式说明:
字符串表达式
示例:
str="Hello World!"
echo `expr length "$str"` # ``不是单引号,表示执行返回该命令的stdout,输出12
echo `expr index "$str" aWd` # 输出7,下标从1开始
echo `expr substr "$str" 2 3` # 输出 ell
整数表达式(仅支持整数)
expr支持普通的算术操作,算术表达式优先级低于字符串表达式,高于逻辑关系表达式。
+ -
加减运算。两端参数会转换为整数,如果转换失败则报错。
* / %
乘,除,取模运算。两端参数会转换为整数,如果转换失败则报错。
() 可以改变优先级,但需要用反斜杠转义
示例:
a=3
b=4
echo `expr $a + $b` # 输出7
echo `expr $a - $b` # 输出-1
echo `expr $a \* $b` # 输出12,*需要转义
echo `expr $a / $b` # 输出0,整除
echo `expr $a % $b` # 输出3
echo `expr \( $a + 1 \) \* \( $b + 1 \)` # 输出20,值为(a + 1) * (b + 1)
逻辑关系表达式
示例:
a=3
b=4
echo `expr $a \> $b` # 输出0,>需要转义
echo `expr $a '<' $b` # 输出1,也可以将特殊字符用引号引起来
echo `expr $a '>=' $b` # 输出0
echo `expr $a \<\= $b` # 输出1
c=0
d=5
echo `expr $c \& $d` # 输出0
echo `expr $a \& $b` # 输出3
echo `expr $c \| $d` # 输出5
echo `expr $a \| $b` # 输出3
read命令用于从标准输入中读取单行数据。当读到文件结束符(ctr+d)时,exit code为1,否则为0。
参数说明
实例:
acs@9e0ebfcd82d7:~$ read name # 读入name的值
acwing yxc # 标准输入
acs@9e0ebfcd82d7:~$ echo $name # 输出name的值
acwing yxc #标准输出
acs@9e0ebfcd82d7:~$ read -p "Please input your name: " -t 30 name # 读入name的值,等待时间30秒
Please input your name: acwing yxc # 标准输入
acs@9e0ebfcd82d7:~$ echo $name # 输出name的值
acwing yxc # 标准输出
示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。
while read name
do
echo ${name}
done
实战时可以用于逐行读取并操作处理文件内容
cat xxx.filetype | while read name
do
echo ${name}
done
grep yyy xxx.filetype | while read name
do
echo ${name}
done
echo用于输出字符串和stdout。命令格式:
echo STRING
显示普通字符串
echo "Hello AC Terminal"
echo Hello AC Terminal # 引号可以省略
显示转义字符
echo "\"Hello AC Terminal\"" # 注意只能使用双引号,如果使用单引号,则不转义原样输出
echo \"Hello AC Terminal\" # 也可以省略双引号
显示变量
name=yxc
echo "My name is $name" # 输出 My name is yxc
显示换行
echo -e "Hi\n" # -e 开启转义
echo "acwing"
输出结果:
Hi
acwing
显示不换行
echo -e "Hi \c" # -e 开启转义 \c 不换行
echo "acwing"
输出结果:
Hi acwing
显示结果定向至文件
echo "Hello World" > output.txt # 将内容以覆盖的方式输出到output.txt中
原样输出字符串,不进行转义或取变量(用单引号)
name=acwing
echo '$name\"'
输出结果
$name\"
显示命令的执行结果
定义命令变量
C=`command`
echo ${C}
echo `date`
输出结果:
Wed Sep 1 11:45:33 CST 2021
printf命令用于格式化输出,类似于C/C++中的printf函数。
默认不会在字符串末尾添加换行符。
命令格式:
printf format-string [arguments...]
用法示例
脚本内容:
printf "%10d.\n" 123 # 占10位,右对齐
printf "%-10.2f.\n" 123.123321 # 占10位,保留2位小数,左对齐
printf "My name is %s\n" "yxc" # 格式化输出字符串
printf "%d * %d = %d\n" 2 3 `expr 2 \* 3` # 表达式的值作为参数
输出结果:
123.
123.12 .
My name is yxc
2 * 3 = 6
因为test命令是逻辑判断命令所以需要echo $?查看命令exitcode确定逻辑判断结果
逻辑运算符&&和||
expr1 && expr2:当expr1为假时,直接忽略expr2
expr1 || expr2:当expr1为真时,直接忽略expr2
test命令
在命令行中输入man test,可以查看test命令的用法。
test命令用于判断文件类型,以及对变量做比较。
test命令用exit code返回结果,而不是使用stdout。0表示真,非0表示假。
例如:
test 2 -lt 3 # 为真,返回值为0
echo $? # 输出上个命令的返回值,输出0
acs@9e0ebfcd82d7:~$ ls # 列出当前目录下的所有文件
homework output.txt test.sh tmp
acs@9e0ebfcd82d7:~$ test -e test.sh && echo "exist" || echo "Not exist"
exist # test.sh 文件存在
acs@9e0ebfcd82d7:~$ test -e test2.sh && echo "exist" || echo "Not exist"
Not exist # testh2.sh 文件不存在
文件类型判断
命令格式:
test -e filename # 判断文件是否存在
test -r filename # 判断文件是否可读
test $a -eq $b # a是否等于b
test -r filename -a -x filename
判断符号[]
[]与test用法几乎一模一样,更常用于if语句中。另外[[]]是[]的加强版,支持的特性更多。
例如:
[ 2 -lt 3 ] # 为真,返回值为0
echo $? # 输出上个命令的返回值,输出0
acs@9e0ebfcd82d7:~$ ls # 列出当前目录下的所有文件
homework output.txt test.sh tmp
acs@9e0ebfcd82d7:~$ [ -e test.sh ] && echo "exist" || echo "Not exist"
exist # test.sh 文件存在
acs@9e0ebfcd82d7:~$ [ -e test2.sh ] && echo "exist" || echo "Not exist"
Not exist # testh2.sh 文件不存在
注意:
[]内的每一项都要用空格隔开
中括号内的变量,最好用双引号括起来:[“$变量”]
中括号内的常数,最好用单或双引号括起来[‘常数’]
避免因为变量值的空格导致识别为多个参数,字符串加引号辅助识别变量边界
例如:
name="acwing yxc"
[ $name == "acwing yxc" ] # 错误,等价于 [ acwing yxc == "acwing yxc" ],参数太多
[ "$name" == "acwing yxc" ] # 正确
if…then形式
类似于C/C++中的if-else语句。
单层if
命令格式:
if condition
then
语句1
语句2
...
fi
示例:
a=3
b=4
if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
then
echo ${a}在范围内
fi
输出结果:
3在范围内
单层if-else
命令格式
if condition
then
语句1
语句2
...
else
语句1
语句2
...
fi
示例:
a=3
b=4
if ! [ "$a" -lt "$b" ]
then
echo ${a}不小于${b}
else
echo ${a}小于${b}
fi
输出结果:
3小于4
日期前缀非零判断及消除
read day
if [ `echo ${day}|grep ^0` ]
then
day1=${day:1:1}
else
day1=${day}
fi
echo ${day1}
多层if-elif-elif-else
命令格式
if condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
...
elif condition
then
语句1
语句2
else
语句1
语句2
...
fi
示例:
a=4
if [ $a -eq 1 ]
then
echo ${a}等于1
elif [ $a -eq 2 ]
then
echo ${a}等于2
elif [ $a -eq 3 ]
then
echo ${a}等于3
else
echo 其他
fi
输出结果:
其他
case…esac形式
类似于C/C++中的switch语句。
命令格式
case $变量名称 in
值1)
语句1
语句2
...
;; # 类似于C/C++中的break
值2)
语句1
语句2
...
;;
*) # 类似于C/C++中的default
语句1
语句2
...
;;
esac
示例:
a=4
case $a in
1)
echo ${a}等于1
;;
2)
echo ${a}等于2
;;
3)
echo ${a}等于3
;;
*)
echo 其他
;;
esac
输出结果:
其他
for…in…do…done
命令格式:
for var in val1 val2 val3
do
语句1
语句2
...
done
将输入参数输出:多个输入参数用空格间隔。
也可用cat和grep的stdout结果作为输入值
acs@f2a8b5544fd2:~$ cat testh.sh
all=`grep i *.t`
for t in $all
do
echo $t
done
all=`cat *.t`
for t in $all
do
echo $t
done
acs@f2a8b5544fd2:~$ sh testh.sh
test.t:i
test1.t:i
i
i
示例1,输出a 2 cc,每个元素一行:
for i in "a" "2" "cc"
do
echo ${i}
done
示例2,输出当前路径下的所有文件名,每个文件名一行:
`command`==$(command):返回command命令的stdout
for file in `ls`
do
echo $file
done
示例3,输出1-10
for i in $(seq 1 10)
do
echo $i
done
示例4,使用{1…10} 或者 {a…z}
for i in {a..z}
do
echo $i
done
for ((…;…;…)) do…done
命令格式:
for ((expression; condition; expression))
do
语句1
语句2
done
示例,输出1-10,每个数占一行:
for ((i=1; i<=10; i++))
do
echo ${i}
done
while…do…done循环
命令格式:
while condition
do
语句1
语句2
...
done
示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。
while read name
do
echo ${name}
done
实战时可以用于逐行读取并操作处理文件内容
cat xxx.filetype | while read name
do
echo ${name}
done
grep yyy xxx.filetype | while read name
do
echo ${name}
done
until…do…done循环
当条件为真时结束。
命令格式:
until condition
do
语句1
语句2
...
done
示例,当用户输入yes或者YES时结束,否则一直等待读入。
until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " word
done
break命令
跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。
break跳出for循环,;;跳出case语句。
示例
while read name
do
for ((i=1;i<=10;i++))
do
case $i in
8)
break
;;
*)
echo $i
;;
esac
done
done
该示例每读入非EOF的字符串,会输出一遍1-7。
该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程。
continue命令
跳出当前循环。
示例:
for ((i=1;i<=10;i++))
do
if [ `expr $i % 2` -eq 0 ]
then
continue
fi
echo $i
done
该程序输出1-10中的所有奇数。
死循环的处理方式
如果AC Terminal可以打开该程序,则输入Ctrl+c即可。
否则可以直接关闭进程:
Shell脚本之函数
bash中的函数类似于C/C++中的函数,但return的返回值与C/C++不同,返回的是exit code,取值为0-255,0表示正常结束(return 0)。
如果想获取函数的输出结果,可以通过echo输出到stdout中,然后通过$(function_name)来获取stdout中的结果。
函数的return值可以通过$?来获取。
函数调用方式
命令格式:
[function] func_name() { # function关键字可以省略
语句1
语句2
...
}
不获取 return值和stdout值
示例
直接调用函数不需要返回值则直接用func_name就行
func() {
name=yxc
echo "Hello $name"
}
func
输出结果:
Hello yxc
获取 return值和stdout值
不写return时,默认return 0。
示例
$(command):得到command命令的stdout(cout)
$?;得到command命令的exitcode(return)
直接调用函数不需要返回值则直接用func_name就行
func() {
name=yxc
echo "Hello $name"
return 123
}
output=$(func)
ret=$?
echo "output = $output"
echo "return = $ret"
输出结果:
output = Hello yxc
return = 123
函数的输入参数
在函数内,$1表示第一个输入参数,$2表示第二个输入参数,依此类推。
注意:函数内的$0仍然是文件名,而不是函数名。
示例:
func() { # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0
word=""
while [ "${word}" != 'y' ] && [ "${word}" != 'n' ]
do
read -p "要进入func($1)函数吗?请输入y/n:" word
done
if [ "$word" == 'n' ]
then
echo 0
return 0
fi
if [ $1 -le 0 ]
then
echo 0
return 0
fi
sum=$(func $(expr $1 - 1))
echo $(expr $sum + $1)
}
echo $(func 10)
输出结果:
55
函数内的局部变量
可以在函数内定义局部变量,作用范围仅在当前函数内。
可以在递归函数中定义局部变量。
命令格式:
local 变量名=变量值
例如:
#! /bin/bash
func() {
local name=yxc
echo $name
}
func
echo $name
输出结果:
yxc
第一行为函数内的name变量,第二行为函数外调用name变量,会发现此时该变量不存在。
exit命令用来退出当前shell脚本进程,并返回一个退出状态;使用$?可以接收这个退出状态exitcode。
exit命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是 0。
exit退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。
示例:
创建脚本test.sh,内容如下:
#! /bin/bash
if [ $# -ne 1 ] # 如果传入参数个数等于1,则正常退出;否则非正常退出。
then
echo "arguments not valid"
exit 1
else
echo "arguments valid"
exit 0
fi
执行该脚本:
acs@9e0ebfcd82d7:~$ chmod +x test.sh
acs@9e0ebfcd82d7:~$ ./test.sh acwing
arguments valid
acs@9e0ebfcd82d7:~$ echo $? # 传入一个参数,则正常退出,exit code为0
0
acs@9e0ebfcd82d7:~$ ./test.sh
arguments not valid
acs@9e0ebfcd82d7:~$ echo $? # 传入参数个数不是1,则非正常退出,exit code为1
1
每个进程默认打开3个文件描述符:
可以用文件重定向将这三个文件重定向输入到其他文件中。
>是覆盖file中内容,>>是将内容从末尾追加到file中
单独使用> /file.filetype可以起到新建/清空文件的效果。
注意:>和>>只能新建文件但是不能新建目录。 输入和输出重定向
echo -e "Hello \c" > output.txt # 将stdout重定向到output.txt中
echo "World" >> output.txt # 将字符串追加到output.txt中
read str < output.txt # 从output.txt中读取字符串
echo $str # 输出结果:Hello World
同时重定向stdin和stdout
创建bash脚本:
#! /bin/bash
read a
read b
echo $(expr "$a" + "$b")
创建input.txt,里面的内容为:
3
4
执行命令:
acs@9e0ebfcd82d7:~$ chmod +x test.sh # 添加可执行权限
acs@9e0ebfcd82d7:~$ ./test.sh < input.txt > output.txt # 从input.txt中读取内容,将输出写入output.txt中
acs@9e0ebfcd82d7:~$ cat output.txt # 查看output.txt中的内容
7
类似于C/C++中的include操作,bash也可以引入其他文件中的代码。
语法格式:
. filename # 注意点和文件名之间有一个空格
或
source filename
示例
创建test1.sh,内容为:
#! /bin/bash
name=yxc # 定义变量name
然后创建test2.sh,内容为:
#! /bin/bash
source test1.sh # 或 . test1.sh
echo My name is: $name # 可以使用test1.sh中的变量
执行命令:
acs@9e0ebfcd82d7:~$ chmod +x test2.sh
acs@9e0ebfcd82d7:~$ ./test2.sh
My name is: yxc
Shell自定义
远程建立session会话,SSH加密信息传输内容。
SSH:Secure Shell,较可靠、专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。最常见的我们可以用它来登录我们的Linux服务器。
Linux:网络操作系统
Linux是基于网络的,诞生于网络。
远程连接上SSH,你就可以轻松操控远在千里之外的Linux服务器,只要有相应的权限,几乎和坐在物理机面前没有区别,哪怕网速很糟糕,实际只是一些加密的字符在传送,shell命令传输需要的带宽很小。
基本用法
远程登录服务器:
ssh user@hostname
账号:(一台服务器(一个公网IP)可以有多个账号)
第一次登录时会提示:
The authenticity of host '123.57.47.211 (123.57.47.211)' can't be established.
ECDSA key fingerprint is SHA256:iy237yysfCe013/l+kpDGfEG9xxHxm0dnxnAbJTPpG8.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
输入yes,然后回车即可。
这样会将该服务器的信息记录在~/.ssh/known_hosts文件中。
然后输入密码即可登录到远程服务器中。
默认登录端口号为22。如果想登录某一特定端口:
ssh user@hostname -p 22
配置文件
创建文件 ~/.ssh/config。
然后在文件中输入:
Host myserver1
HostName IP地址或域名
User 用户名
Host myserver2
HostName IP地址或域名
User 用户名
之后再使用服务器时,可以直接使用别名myserver1、myserver2。
密钥登录
SSH登录及其原理详解
SSH 共有两种登录方式:
口令验证登录
服务器生成公钥和私钥
客户端发起连接请求,服务器将公钥发给客户端
客户端生成口令(服务器密码),并用服务器发来的公钥加密,发送给服务器
服务器通过私钥解密,拿到口令(服务器密码)
如果正确则认证成功
密钥验证登录
创建密钥:
ssh-keygen
然后一直回车即可。
执行结束后,~/.ssh/目录下会多两个文件:
之后想免密码登录哪个服务器,就将公钥传给哪个服务器即可。
例如,想免密登录myserver服务器。则将公钥中的内容,复制到myserver中的~/.ssh/authorized_keys文件里即可。
也可以使用如下命令一键添加公钥到远程服务器:
前提:配置好.ssh/config中的信息。myserver为对应的
ssh-copy-id myserver
执行命令
命令格式:
ssh user@hostname command
例如:
ssh user@hostname ls -a
或者
# 单引号中的$i可以求值
ssh myserver 'for ((i = 0; i < 10; i ++ )) do echo $i; done'
或者
# 双引号中的$i不可以求值
ssh myserver "for ((i = 0; i < 10; i ++ )) do echo $i; done"
前提:源和端网络能通信
主机上ping一下IP看看网络是否能通信。
destination必须是绝对路径
source是本地主机文件可以用相对路径
scp source ------> destination
scp source username@IP/域名:destination
或
scp username@IP/域名:source destination
前提:配置SSH远程登录
scp 命令是用于通过 SSH 协议安全地将文件复制到远程系统和从远程系统复制文件到本地的命令。使用 SSH 意味着它享有与 SSH相同级别的数据加密,因此被认为是跨两个远程主机传输文件的安全方式。
基本用法
命令格式:
scp source destination
将source路径下的文件复制到destination中
一次复制多个文件:
scp source1 source2 destination
复制文件夹:
scp -r ~/tmp myserver:/home/user/
将本地家目录中的tmp文件夹复制到myserver(别名)服务器中的/home/user/目录下。
默认:myserver为/home/user/目录下。
scp -r ~/tmp myserver:homework/
将本地家目录中的tmp文件夹复制到myserver服务器中的~/homework/目录下。
scp -r myserver:homework .
将myserver服务器中的~/homework/文件夹复制到本地的当前路径下。
指定服务器的端口号:
scp -P 22 source1 source2 destination
注意: scp的-r -P等参数尽量加在source和destination之前。
使用scp配置其他远程服务器的vim和tmux
scp ~/.vimrc ~/.tmux.conf myserver:
`date空格 ‘+日期格式’`
date -d "-3 day" +%Y%m%d
:默认当前日期减去三天的YYYYMMDD #! /bin/bash
first=$1
second=$2
while [ "$first" != "$second" ]
do
echo $first
first=`date -d "-1 days ago ${first}" +%Y%m%d`
done
注意:中间是两个英文句号
for lastdata in {20221201…20221213}
do
…
done
lastdate=`date -d "-6 day" +%Y%m%d`
currdate=`date +%Y%m%d`
echo SMS
for ((monday=${lastdate}; monday<=${currdate}; monday++))
do
......
done
概念
能在terminal看见输出结果的都为stdout命令(查看命令:cat,ls等)。
管道类似于文件重定向,从左到右执行,可以将前一个命令的stdout重定向到下一个命令的stdin。
要点
与文件重定向的区别
举例
统计当前目录下所有python文件的总行数,其中find、xargs、wc等命令可以参考常用命令这一节内容。
find . -name '*.txt' | xargs cat | wc -l
首先寻找当前目录下所有txt文件,然后通过xargs将stdout转化为文件参数给cat,,最后由wc将cat展示的文件内容进行处理输出。
环境变量
概念
Linux系统中会用很多环境变量来记录配置信息。
环境变量类似于全局变量,可以被各个进程访问到。我们可以通过修改环境变量来方便地修改系统配置。
查看
列出当前环境下的所有环境变量:
env # 显示当前用户的变量
set # 显示当前shell的变量,包括当前用户的变量;
export # 显示当前导出成用户变量的shell变量
输出某个环境变量的值:
echo $PATH
修改
环境变量的定义、修改、删除操作可以参考shell语法——变量这一节的内容。
vim ~/.bashrc
为了将对环境变量的修改应用到未来所有环境下,可以将修改命令放到~/.bashrc文件中。
修改完~/.bashrc文件后,记得执行source ~/.bashrc,来将修改应用到当前的bash环境下。
为何将修改命令放到~/.bashrc,就可以确保修改会影响未来所有的环境呢?
常见环境变量
可用echo ${环境变量},查看对应环境变量的数值。
可以修改~/.bashrc文件,将自己写的命令行程序放在PATH环境变量中,这样就可以使用自己的命令了
linux下自定义命令的几种方式
linux自定义命令
top:查看所有进程的信息(Linux的任务管理器)
df -h:查看硬盘使用情况
free -h:查看内存使用情况
du -sh:查看当前目录下文件占用的总硬盘空间。
ps aux:查看所有进程
ps -ef 指令详解
ps -ef | grep 进程名配合食用
kill -9 pid:强制杀死编号为pid的进程
netstat -nt:查看所有网络连接
w:列出当前登陆的用户
ping www.baidu.com:检查是否连网
d r w x | r w x | r w x
自己|同组|其他
d:是否为目录,r:是否可读,w:是否可写,x:是否可执行
chmod:修改文件权限
file 文件:查看文件编码格式
file [-bcLvz][-f <名称文件>][-m <魔法数字文件>…][文件或目录…]
中文乱码的原因:编码和解码不一致
只有中文会出现乱码问题
文本检索
grep实用案例
(查询文本)grep xxx:从stdin中读入若干行数据,如果某行中包含xxx,则输出该行(逐行输出);否则忽略该行。
默认匹配模式是模糊匹配
-c:统计符合字符串条件的行数
-v:显示不包括文本的所有信息
-w:精准匹配完整单词(同行完整单词分隔符可为逗号和空格)
可以配合ps,ls等stdout命令食用:查询进程/目录中是否存在对应进程和文件。
grep详解
Linux命令 zgrep
使用zgrep命令可以在压缩文件中调用grep按正则表达式来搜索
zgrep -hw
grep xxx ./*.filetype:将path下的全部filetype文件内容进行查询匹配逐行输出=》文件名:匹配列
(分析文本)wc:统计行数、单词数、字节数
grep xxx | wc -l
awk xxx | wc -l
或
wc -l xxx.file
cut:分割一行内容(-d:列,-c:字符)
sort:将每行内容按字典序排序
文件检索
find /path/to/directory/ -name ‘*.py’:搜索/path/to/directory/文件路径下的所有*.py文件
which:会在环境变量$PATH设置的目录里查找符合条件的可执行文件。
find只能查文件,which只可以查可执行命令(ls,cat,软件自定义命令等)
tree:展示当前目录的文件结构
ag xxx:搜索当前目录下的所有文件,检索xxx字符串
xargs:将stdin中的数据用空格或回车分割成命令行参数
全部输出
cat:一次性输出文件全部内容
vim:增删改查文件全部内容
部分输出
more:浏览文件内容
less:与more类似,功能更全
head -3 xxx:展示xxx的前3行内容
tail -3 xxx:展示xxx末尾3行内容
tail -f filename 会把 filename 文件里的最尾部十行的内容显示在屏幕上,并且不断刷新follow跟踪,只要 filename 更新就可以看到最新的文件内容。
常见用法:
首先写一个tmpl模板文件然后写一个脚本基于tmpl模板文件替换占位符传参。
sh 脚本.sh 变量参数参数
sed -i /\${tmpl参数占位符} /${变量参数} tmpl复制份
替换特殊字符(利用反斜杠)
反斜杠用法
Linux awk命令详解
linux之awk超详解
linux awk数组操作详细介绍
cat获得文件内容,grep分析提取文件内容,awk解析操作需求内容的每一行。
awk将"作为文本分隔符,然后提取第四列作为sum数组的定位下标并将其对应的数组元素值加一,处理完全部内容后,END最后用for循环逐行输出数组值(一次输出占一行)。
无序:cat XXX.filetype | grep "yyy" | awk -F'"' '{sum[$4]+=1} END {for(k in sum) print k ":" sum[k]}'
有序(已知:k<=100):cat XXX.filetype | grep "yyy" | awk -F'"' '{sum[$4]+=1} END {for(k=1;k<=100;k++) if (sum[k]>0) print k ":" sum[k]}'
awk -F, '{SUM['$number']=SUM['$number']+1} END {for (i in SUM) print i,SUM[i]} '
注意(万物皆字符串,一劳永逸):
若数组内使用自定义变量则AWK的数组下标直接用"‘’"来声明字符串变量,防止变量为字符串非数值作为下标导致出错。
未使用双引号则默认为数值,反之可为字符串类型(双引号需要在变量最外侧标明)。
'{SUM["'$number'"]=SUM["'$number'"]+$4}'
若报错则说明检索的文本没有对应属性导致SUM[]中下标为空。
history:展示当前用户的历史操作。内容存放在~/.bash_history中
whoami:查询当前用户类型:是否为root
clear:清屏
哈希值:原文为key,对应转化为哈希值value
md5sum:计算md5哈希值(将文件内容转为唯一32位字符,文件内容变化一点,则对应32位字符也会变化)
time command:统计command命令的执行时间
ipython3:交互式python3环境。可以当做计算器,或者批量管理文件。
watch -n 0.1 command:每0.1秒执行一次command命令
tar:压缩文件
diff xxx yyy:查找文件xxx与yyy的不同点
安装软件(权限不够,sudo来凑)
root在linux中具有无上权限,啥都可以做
全部查看命令都常用:ctr+f:查看
nohup命令若是出现在for或者while循环中注意控制数量,防止服务端挂载过多线程。
while true
do
# 跑中:zgrep -hw $number ./xxxx/yyyy.log.gz >> ./zzzz${currdate}/$number.log
# 跑完结果:grep --color=auto zgrep
threadnum=`ps -ef | grep zgrep | awk '{print $11}' | sort | uniq | wc -l `
# 实际上因为特殊的主机服务端,会自动对挂载的进程,产生多个线程提升速度,所以用sort和uniq对#11=number排序去重后wc计算实际挂载数量。
echo $threadnum
# zgrep进程数是否大于10
if [ $threadnum -gt 10 ]; then
# 十一条zgrep还在跑则当前进程停一下等等,防止服务端挂载过多线程
sleep 120
else
# 少于十一条zgrep则继续挂载zgrep进程
break
fi
done
for和while可以以空格或者回车为分割符,逐个循环读取(echo,``,cat,grep)stdout中的值并在循环体内操作。
上述内容中有介绍。
拒绝蛮力,高效查看Linux日志文件!
操作压缩文件命令
# 类似cat,同时解压并输出内容
zcat app.log.gz
# 类似grep,同时解压并查找内容
zgrep -m 10 ERROR app.log.gz
# 类似less,同时解压并查看内容
zless app.log.gz
less:与more类似,功能更全
less好处:另开界面,不会占据输入命令的界面且限量显示文本。
alias rm='Are you crazy?'
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号。
单引号与双引号的区别:
name=yxc # 不用引号
echo 'hello, $name \"hh\"' # 单引号字符串,输出 hello, $name \"hh\"
echo "hello, $name \"hh\"" # 双引号字符串,输出 hello, yxc "hh"
单双引号可以相互包容并原样显示,无需转义字符。
可用于在字符串变量命令中声明字符串。
多用于单引号包双引号,这样可以执行字符串中的命令。
例如:若数组内使用自定义变量则AWK的数组下标直接用"‘’"来使用变量,防止变量为字符串非数值作为下标导致出错。
未使用双引号则默认为数值,反之可为字符串类型(万物皆字符串,一劳永逸)。
'{SUM["$number"]=SUM["$number"]+$4}'
expect就是一个维持源端主机shell命令通信的桥梁,建立连接后,在本地的源主机上,将shell命令传输到目标端主机上运行并返回运行结果。
注意:两个主机需要网络可互通才行,例如源和端可以实现scp传输文件或者ping一下。
主机上ping一下IP看看网络是否能通信。
expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。
expect自动交互流程:
spawn启动指定进程—expect获取指定关键字—send向指定程序发送指定字符—执行完成退出.
expect常用命令
spawn 交互程序开始后面跟命令或者指定程序
expect 等待一个进程的反馈,if获取匹配信息匹配成功则执行expect后面的程序动作
send exp_send 用于发送指定的字符串信息
exp_continue 在expect中多次匹配就需要用到
send_user 用来打印输出相当于shell中的echo
exit 退出expect脚本
eof expect执行结束 退出
set 定义变量
puts 输出变量
set timeout 设置超时时间 :桥梁维持时间
interact 退出自动化,开始允许用户交互
自动登录脚本
自动远程登录脚本:bqh-nfs-123机器免输密登录bqh-back-124机器上
[root@bqh-nfs-123 scripts]# vim test.exp
#!/usr/bin/expect -f #expect的路径,which expect查询获取
set timeout 20 #连接超时
set host "192.168.0.124"
set password "123456"
spawn ssh root@$host #登录服务器用户+地址
expect { #等待接收进程返回的字符串
"yes/no" {send "yes\n";exp_continue} #等待输入yes
"password:" {send "$password\n"} #等待输入密码
}
interact #将脚本的控制权交给用户,用户可继续输入命令
大神总结-linux,curl命令发送各种请求详解
前提:
Linux主机和容器网络能通,所以可以通过linux主机访问容器。
主机上ping一下IP看看网络是否能通信。
简介:
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。
当你经常面对api时,curl将是你重要学习的工具,因为curl可以让你不需要浏览器也能作为Http客户端发送请求。而且它是跨平台的,Linux、Windows、Mac都会执行的很好。
例子:
curl -s -X POST http://IP:port/userInfo?userId=${参数变量} >> sysncinfo.log
-s, --silent Silent模式。不输出任务内容
-X, --request COMMAND 使用指定的post/get请求命令
shell脚本若需要用到#!则必须放在首行,若首行是空格则在不同版本下会有问题。
一般情况:第一行的内容指定了shell脚本解释器的路径,而且这个指定路径只能放在文件的第一行。第一行写错或者不写时,系统会有一个默认的解释器进行解释。
每个脚本开头都使用"#!",#!实际上是一个2字节魔法数字,这是指定一个文件类型的特殊标记,在这种情况下,指的就是一个可执行的脚本。在#!之后,接一个路径名,这个路径名指定了一个解释脚本命令的程序,这个程序可以是shell,程序语言或者任意一个通用程序。
报错的原因是: mkdir创建多级目录时需要加参数 p。
mkdir -p /A/B:
在if判断中[]这个符号有特殊要求。[]与代码之间要有空格隔开的。
if空格[空格condition空格]
then
语句1
语句2
...
fi
注意:不要在变量定义时等号之间乱加空格并且赋值时,若值包含空格则需要用引号包起来。
正确格式:
定义变量,不需要加$符号,例如:
声明即定义
name1='yxc' # 单引号定义字符串
name2="yxc" # 双引号定义字符串
name3=yxc # 也可以不加引号,同样表示字符串
>是覆盖file中内容,>>是将内容从末尾追加到file中
单独使用> /file.filetype可以起到新建/清空文件的效果。
注意:>和>>只能新建文件但是不能新建目录。
本地终端跑一跑看看报错信息。
或者查看nohup.out
解决:ln: failed to create symbolic link ‘/usr/bin/java’: File exists
Linux中的硬链接、软链接及其基本原理
实际上就是创建快捷方式。
软链接,以路径的形式存在。类似于Windows操作系统中的快捷方式。
ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化;
无论是软链接还是硬链接,文件都保持同步变化。
in在linux中的意思是“创建链接”,in命令用于为指定的文件在另一个位置建立同步的链接,语法为“ln 参数 源文件 目标文件”;默认情况下创建硬链接,当参数设置为“-s”时,对源文件创建软链接。
-s 命令的意思是增加符号链接,起到一个链接的作用。
ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间。
第一,ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化;第二,ln的链接又分软链接和硬链接两种,软链接就是ln –s 源文件目标文件,它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间,硬链接 ln 源文件 目标文件,没有参数-s,它会在你选定的位置上生成一个和源文件大小相同的文件,无论是软链接还是硬链接,文件都保持同步变化。
1.命令格式:
ln [参数][源文件或目录][目标文件或目录]
软链接:
ln -s [源文件或目录][目标文件或目录]
把 -s 命令修改成 -sf 命令;-f 命令的意思是强制执行,也就意味着如果不存在就执行创建,存在就执行覆盖掉。
chmod:修改文件权限