Linux高级命令
安装软件
(1)ubuntu deb
(2)redhat rpm
软件包的格式
sudo dpkg -i 软件名
sudo dpkg -l //列举ubuntu上安装的所有软件
sudo dpkg -L 软件名 //列举这个软件相关的所有路径(帮助文档,man手册,软件安装的位置信息 等)
sudo dpkg -s sl //查看软件的安装的状态(详细)
在线安装apt-get,如果软件有依赖程序,这些程序会被一并安装上去
选择软件源:
software & updates -> download from-->选择软件源
sudo apt-get update //更新源
/etc/apt/source.list //记录源的路径
/var/lib/apt/lists //这个服务器上的各个安装包的信息的目录
下载安装
sudo apt-get install 软件名
sudo apt-get remove 软件名 //卸载
sudo apt-get source 软件名 //下载软件的源码
sudo apt-get download 软件名 //下载软件,不进行安装(当前目录下)
sudo apt-get clean //清除目录下 /var/cache/apt/archives的安装包
压缩命令
(1)压缩的对象是文件: .gz .bz2 .xz
gzip/gunzip --->xxx.gz
bzip2/bunzip2 --->xxx.bz2
xz/unxz --->xxx.xz
压缩率:.xz > .gz > .bz2
压缩速率:.xz < .gz < .bz2c
如何使用?
gzip +文件名
注意:压缩和解压缩源文件被替换
(2)归档的对象是目录(打包、拆包)
将一个目录归档成一个文件,或者将这个归档后的文件重新释放变成一个目录都是用如下命令:
tar 命令
-c:创建归档文件
-x: 释放归档文件
-z: 压缩成gzip格式
-j: 压缩成bzip2格式
-J: 压缩成xz格式
-v: 显示过程
-f: 后面跟的是文件的名字
1、归档
tar -cvf hello.tar hello --->将hello打包成hello.tar
tar -xvf hello.tar --->将hello.tar拆成hello目录
2、打包并压缩
tar -czf hello.tar.gz hello
tar -cjvf hello.tar.bzip2 hello
3、解压缩
tar -xjvf hello.tar.bzip2 //只能解压缩.bzip2格式
tar -xvf 压缩包 //万能拆包命名
4、在拆包和解压缩的时候指定路径
tar -xvf -C 压缩包
文件相关
文件查找
ls
cat(-n:显示行号)
//查看当前ubuntu的版本号
cat /etc/issue
vim—>使用vim配置自动补全一些信息
vim /home/jsetc/.vim/snippets/c.snippets
hdr + tab -->文件介绍
funh + Tab 函数的注释
Inc + Tab 补全头文件
main + Tab 补全main函数
head:显示前些行的命令
head 文件名 默认显示文件的前10行
head -line 文件名 显示前line行
tail:显示后些行命名
tail 文件名 显示文件末尾的10行
tail -line 文件名 显示后line(行号)行
more/less 文件名 查看文件,但是在工作中不用
file 文件名 查看文件的格式
file a.out
练习:
/etc/passwd 保存用户信息的文件
/ect/shadow 保存用户密码的文件
使用上述的任意命令,显示/etc/passwd文件的第41行的内容
|:管道符 -->将一个命令的结果作为后一个命令的输入
cat -n /etc/passwd |tail -4|head -1
文件的追加
>:重定向
>>:追加
echo "字符串" 将字符串在终端显示
echo -n "字符串" 将字符串在终端显示不换行
文件的统计
文件内容的搜索
grep "想要搜索的字符串" 路径/文件名 参数
-n:显示行号
-R:递归搜索
-w:搜索的是单词
-i:忽略大小写
"^main":搜索以main开头的行
"main$":搜索以main开头的行
"^main$":搜索行只有main
文件的查找
find:查找文件
find 路径 -name 文件的名字
find ~ n -name 1.c
shell
shell概念和使用
shell:就是命令解析器
shell脚本就是将一堆命令的特有的控制语句放在.sh结尾的文件中,这个文件就被叫做shell脚本
使用
1.文件的命名(结尾是.sh)
vim 01test.sh
2.脚本的第一行
• #!/bin/bash: 标识解析此脚本的shell是bash
3. 脚本文件是不需要编译的,直接由命令行解析器解析
4. 执行脚本 ./01test.sh (脚本需要有可执行权限)-->chomd a+x 01test.sh bash 01test.sh source 01test.sh
5.三种执行方式的区别
1)./执行脚本的时候需要可执行权限,而bash和source都不需要可执行权限
2)./和bash解析脚本的时候会新开子终端,在子终端中解析,将解析的结果返回到当前终端, source是直接在当前终端解析。
练习:脚本实现
1.在自己的用户主目录下新建两个子目录 subdir1 subdir2
2.将/etc/passwd文件拷贝到subdir1,将/etc/group拷贝subdir2中
3.将subdir2重命名位subdir
4.对subdir1进行打包并压缩成xz格式
5.将打包后的xz格式文件拷贝到subdir目录下
6.解压subdir目录下的压缩格式文件
7.查看subdir目录下的所有文件
#! /bin/bash
mkdir subdir1
mkdir subdir2
cp /etc/passwd subdir1
cp /etc/group subdir2
mv subdir2 subdir
tar -cJvf subdir1.tar.xz subdir1
cp subdir1.tar.xz subdir
cd subdir
tar -xJvf subdir1.tar.xz
ls
shell脚本中的变量
1.变量不需要定义
2.变量没有对应的类型
3.变量赋值的时候直接写=(等号前后不能有空格)
4.在shell脚本中,所有的变量被赋的值都认为是字符串
5.赋值的区别如下
var1=123 -->字符串之间不能有空格
var1='123 456' -->可以有空格
var2="123 $var1" -->可以有空格,可以调用新的变量
6.变量的引用
$var1 ${var1}
7.使用echo来打印变量
echo $var1
8.通过位置变量可以进行命令行的传递参数
$0 //脚本的名字
$1 $2....$9 ${10}...${n} //参数对应位置的字符串
$@或$* //命令行传递的所有的参数(脚本名除外)
$# //命令行参数的个数
9. unset 变量名 //清除变量的值 readonly 变量 //标识这个变量是只读的
练习
通过位置变量向脚本中传入两个字符串分别赋值给var1和var2,然后将这两个变量的值进行交换后输出。
#! /bin/bash
var1="$1"
var2="$2"
var3="$var1"
var1="$var2"
var2="$var3"
echo $var1
echo $var2
shell脚本中的数组
shell脚本只有一维数组,没有多维数组 数组没有成员个数的限制
- 数组的格式如下
arr=(1 2 3 4 "www.baidu.com")
arr=([0]=11 [5]=wer)
- 数组成员访问方法
${arr[0]} ${arr[n]} #访问数组中的某一个成员
${arr[@]} 或者 ${arr[*]} #访问数组中所有的成员
${#arr[@]} 或者 ${#arr[*]} #数组中成员的个数
- 数组成员的追加
arr=(${arr[@]} "www.jsetc.com") #在数组的尾部进行追加
arr[6]="www.github.com"
#!/bin/bash arr=(11 22 33 44 55 "www.baidu.com")
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
echo ${arr[3]}
echo ${arr[4]}
echo ${arr[5]}
#显示所有数组
echo ${arr[@]}
echo ${arr[*]}
#显示数组个数
echo ${#arr[*]}
#追加数组
arr=(${arr[*]} "www.github.com")
echo ${arr[@]}
arr[7]=hello
echo ${arr[@]}
arr[8]=world
echo ${arr[@]}
len=${#arr[*]}
echo $len
#最后一个元素的字节数
echo "last member size = ${#arr[$len-1]}"
练习
通过命令行输入一些字符串,将这些字符串赋值给数组,然后求数组成员的个数,打印数组所有的成员,将数 组的第一个成员的值改为“hello world” ,打印数组最后一个成员的字节个数。
#! /bin/bash
arr=($*)
echo ${arr[@]}
len=${#arr[*]}
echo $len
arr[0]="hello world"
echo ${arr[@]}
echo "last member size = ${#arr[$len-1]}"
shell的运算
shell的运算符
算术运算符:
+ -
* / %
** 幂运算
++ --
! && ||
< <= > >=
<< >>
~ | & ^
= += -= ...
shell中的变量被赋的值都是字符串,所以它不能够进行算术运算,如果向执行算术运算必须使用特殊的标识 来完成。
(()) 整数运算
$[] 整数运算
expr 整数运算,字符串的运算
(())如何使用
(($va1 + $var2))
((va1+ var2)) #在(())内部变量可以有$,也可以没有$符号,在运算符前后可以加空格,也可以没有 空格
sum=$((var++)) #如果要将一个表达式的结果赋值给变量,需要在(())前加$符号
tt=$((表达式1,表达式2,表达式3,...))#所有的表达式都会参与运算最后一个表达式的结果赋值给tt变量 在(())中可以做复杂的运算
for((i = 0; i < 100;i++))
{
((sum+=i))
}
echo $sum
#!/bin/bash
var1=123
var2=456
sum=$((var1 + var2))
echo $sum ((var1++))
echo $var1
tt=$((var1++,++var2,9**2,var1++))
echo $tt
echo $var1
echo $var2
sum=0
for((i = 0;i <=100;i++))
{
((sum += i))
}
echo $sum
练习:
通过命令行输入数组,对数组的成员求和
#! /bin/bash
arr=($*)
len=${#arr[*]}
sum=0
for((i=0;i<=len;i++))
{
((sum+=arr[i]))
}
echo $sum
$[ ]如何使用
var1=12
ret=$[var1++]
echo $[var1++] #s[]一定需要有变量去承接结果,如果不使用变量去接收结果,就必须使用echo输出
ret=$[var2 + var3] #在$[]里面,可以有空格,也可以没有空格,可以有$,也可以没有$
#在$[]中不允许做复杂的运算,比如for循环
ret=$[var1++,var2++,3**5]
echo $ret #最后一个表达式的结果解释整个表达式的结果
#!/bin/bash
var1=12
var2=13
expr $var1 + $var2
sum=`expr $var1 \* $var1`
echo $sum
#mul=`expr 6 \** 3`
#echo $mul
var3=`ls`
echo $var3
#!/bin/bash
var1=12
ret=$[var1++]
echo $[var1++]
var2=13
var3=15
ret=$[var2 + var3]
echo $ret
:<<hello
echo "hello world"
hello
ret=$[var1++,var2++,3**5]
echo $ret
expr的使用
var1=12
var2=13
expr $var1 + $var2
[1]expr在运算完之后结果会自动显示
[2]expr在使用的变量的时候,变量前一定要有$符号
[3]运输符前后要加空格,如果不加空格,会出错
sum=`expr $var1 + $var2`
[4]如果要将expr的运算的结果给新的变量,需要使用置换
mul=`expr 6 \* 3`
[5]expr在进行*运算的时候,如果不使用转义符号,它认为是通配符好,不能进行乘法运算
注:
var1=`ls`
var1=$(ls)
[6] 使用expr计算字符串的长度
expr length $var2 (注意:var变量中不能有空 格,有空格会出现语法错误)
[7] 使用expr在源字符串中查找字串的位置
expr index $var "wh" (如果第一个字符没有在原字符串中出现,就会去查找下一个字符,直到找 到字符在原字符串中的位置,没有找到返回0)
[8] 提取字符串
expr substr $var 起始位置 结束位置
[9] 字符串的匹配
expr match $var "www.h"
#!/bin/bash
var1=12
var2=13
expr $var1 + $var2
sum=`expr $var1 \* $var1`
echo $sum
#mul=`expr 6 \** 3`
#echo $mul
var3=`ls`
echo $var3
#!/bin/bash
var1=www.baidu.com
expr length $var1
expr index $var1 "ai"
len=`expr length $var1`
expr substr $var1 5 $len
expr match $var1 "www."
shell的控制语句
(1)if的语句格式
if [ 判断条件 ] -->这里的[]可以写成test
then
if成立执行的语句
fi
if [ 判断条件 ] -->这里的[]可以写成test
then
if成立执行的语句
else
if不成立执行的语句
fi
if [ 判断条件 ] -->这里的[]可以写成test
then
if成立执行的语句
elif [ 判断条件2 ]
then
判断条件2成立的语句
else
上述都不成立的语句
fi
(2)对数字的判断
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
(3)逻辑运算
&& ---> -a
|| ---> -o
! ---> !
#!/bin/bash
#if [ $1 -gt 10 ]
if test $1 -gt 10
then
echo "hello world"
else
echo "i am a good man"
fi
练习
从终端输入一个学生的成绩(0-100),输出其成绩的等级(90-100->A 80-90->B 60-80->C 0- 60->D)
#!/bin/bash
if [ $1 -lt 0 -o $1 -gt 100 ]
then
echo "input error,try again"
exit 1
fi
if [ $1 -ge 90 -a $1 -le 100 ]
then
echo "A"
elif [ $1 -ge 80 -a $1 -lt 90 ]
then
echo "B"
elif [ $1 -ge 60 -a $1 -lt 80 ]
then
echo "C"
else
echo "D"
fi
作业
1.使用c语言和shell脚本实现一个实时时钟 #!/bin/bash
year=2022
month=7
day=26
hour=11
min=20
sec=0
for((;;))
{
((sec++))
sleep 1
printf "%d-%02d-%02d %02d:%02d:%02d\r" $year $month $day $hour $min $sec
}
shell脚本的输入命令
read 变量名 -->类似于c的scanf
- 将变量从终端读取到shell
- read可以同时读取多个变量的值
read 变量1 变量2
- read可以跟一个-p属性用于打印提示
read -p "input var1 var2 >"var1 var2
- read可以通过-a参数读取一个数组
read -p "input arr" -a arr
echo ${arr[@]}
- read加-n num 指定读取Num个字符
read -n 5 var1
echo $var1
- 取消回显
read -p "passwd :" -s var1
- 在sec秒内如果没有输入,read会向下执行,如果有输入,则读取输入的数据
read -p "input :" -t 3 var1
echo $var1
read后面的参数:
-p:输入的时候提示
-a: 输入的是数组
-n:指定输入字符的个数
-s:取消回显
-t:指定超时时间
练习:输入两个字符串,比较大小
#!/bin/bash
read -p "input(str1 str2): " var1 var2
if [ -n "$var1" -a -n "$var2" ]
then
if [ "$var1" \> "$var2" ]
then
echo "str1 > str2"
elif [ $var1 \< $var2 ]
then
echo "str1 < str2"
else
echo "str1 = str2"
fi
else
echo "please input string,str1 or str2 is NULL"
exit 1
fi
shell中判断的使用
#判断字符串
-z 判断字符串是否为空
-n 判断字符串是否不为空
=或者== 判断字符串是否相等
!= 判断字符串是否不相等
\> 判断是否大于
\< 判断是否小于
#对文件类型的判断
-e:判断文件是否存在
-s:判断文件是否存在,并且判断文件是否为空
-b:判断文件是否存在,并且判断文件是否是块设备文件
-c:判断文件是否存在,并且判断文件是否是字符设备文件
-d:判断文件是否存在,并且判断文件是否是目录
-f:判断文件是否存在,并且判断文件是否是普通文件
-L:判断文件是否存在,并且判断文件是否是链接文件
-S:判断文件是否存在,并且判断文件是否是套接字文件
-p:判断文件是否存在,并且判断文件是否是管道文件
#对文件权限的判断
-r:判断是否具备可读权限
-w:判断是否具备可写权限
-x:判断是否具备可执行权限
#!/bin/bash
read -p "input filename> " file
if test -e "$file" -a -n "$file"
then
if test -L $file
then
echo "这是链接文件"
elif test -f $file
then
echo "这是普通文件"
elif test -d $file
then
echo "这是一个目录"
elif test -c $file
then
echo "这是字符设备文件"
elif test -s $file
then
echo "这是套接字文件"
elif test -p $file
then
echo "这是g管道文件"
fi
else
echo "file not found ,please check input filename"
fi
练习
向脚本输入一个文件的名字,判断输入是否不为空,如果不为空,判断是否是普通文件 如果是普通文件,再 判断文件是否具备写的权限如果文件不具备就添加写的权限,向文件尾部追加hello world这句话。
#!/bin/bash
read -p "input filename >" file
if [ -n "$file" ]
then
if [ -f "$file" ]
then
if [ ! -w "$file" ]
then
chmod u+w $file
fi
echo “hello world” >> $file
else
echo "输入的不是一个普通文件"
exit 1
fi
else
echo "input try again"
exit 1
fi
case in 语句
case 变量 in
匹配选项1)
语句1;
匹配选项2)
语句2;
匹配选项n)
语句n;
匹配选项的格式:
*:匹配任意字符
[字符1字符n]:匹配[]内部任意一个字符
“y”|"yes" :如果有多个可以使用|
,|.|:|\"|?: 注意使用者转义字符
#!/bin/bash
read -p "input number >" num
case $num in
1)
echo "星期一"
;;
2)
echo "星期二"
;;
*)
echo "输入错误"
;;
esac
#!/bin/bash
read -p "input char > " cc
case $cc in
[0-9]|"10")
echo "这是一个数字"
;;
[a-zA-Z])
echo "这是一个字母"
;;
,|.|:|\"|?)
echo "这是一个标点符号"
;;
*)
echo "输入错误"
;;
esac
while循环
while 循环条件
do
循环体
done
#!/bin/bash
sum=0
i=0
while [ $i -le 100 ]
do
((sum += i++))
done
echo $sum
练习
在用户家目录下创建两个目录file-dir和dir-dir
如果目录已经存在了,就不需要创建了,询问用户是否需要对目录清空[Y/N] y n,yes no
输入一个路径,判断这个路径是否存在,如果存在,将这个目录下的文件拷贝到file-dir,将目录拷贝到 dir-dir下
统计拷贝的文件和目录的个数,将文件的个数和目录的个数打印出来
#!/bin/bash
arr=("/home/user/Xshell/file-dir" "/home/user/Xshell/dir-dir")
i=0
while test $i -lt ${#arr[@]}
do
if [ -d ${arr[$i]} ]
then
echo -n "是否需要清空${arr[$i]}目录 『Y/N』"
read chose
case $chose in
"Y"|"y"|"yes"|"YES")
echo "正在清空${arr[Si]}中"
rm -rf ${arr[$i]}/*
echo "${arr[$i]}已经被清空 "
;;
"N"|"n"|"no"|"NO")
echo "${arr[$i]}目录下的内容没有被清空"
;;
*)
echo "输入错误"
;;
esac
else
mkdir ${arr[$i]}
echo "新建了 ${arr[$i]}这个目录"
fi
((i++))
done
while true
do
file=0
dir=0
read -p "enter a path>" path
if [ -d $path ]
then
arr1=(`ls $path`)
j=0
while test $j -lt ${#arr1[@]}
do
if [ -f $path/${arr1[$j]} ]
then
echo "正在拷贝${arr1[$j]}文件中... "
cp $path/${arr1[$j]} ${arr[0]}
((file++))
elif [ -d $path/${arr[$j]} ]
then
echo "正在拷贝 ${arr1[$j]}目录中..."
cp $path/${arr[$j]} ${arr[1]} -r
((dir++))
fi
((j++))
done
elif [ "$path" = "quit" ]
then
echo "退出程序..."
exit 1
else
echo "输入的路径不存在,请重试..."
continue
fi
echo "拷贝文件的个数:$file"
echo "拷贝目录的个数:$dir"
done
for 循环
- 用法1(C风格)
for((i = 0 ; i < 100;i++))
do
循环体
done
- 用法2(shell特有的for循环)
for 变量 in 单词列表
do
循环体
done
注意:单词列表的格式
格式1: Ubuntu windows ios redhat
格式2: `ls`
格式3:{start..end}
格式4:如果in和后面的单词列表是缺省的,此时单词列表是命令行的参数
#!/bin/bash
for var in ubuntu windows ios iphone
do
echo $var
done
#!/bin/bash
for var in `ls`
do
echo $var
done
#!/bin/bash
:<<EOF
sum=0
for var in {1..100}
do
((sum += var))
done
echo $sum
EOF
for var in {A..Z}
do
echo $var
done
- select in增强交互效果的循环语句
select 变量 in 单词列表
do
循环体
done
#!/bin/bash
select var in windows ubuntu ios Android
do
echo $var
done
#!/bin/bash
select var in windows ubuntu ios Andorid
do
case $var in
"windows")
echo "welcome to window"
;;
"ubuntu")
echo "welcome to ubuntu"
;;
"ios")
echo "welcome to ios"
;;
"Andorid")
echo "welcome to Andorid"
;;
*)
echo "error..."
;;
esac
done
break和continue
和c语言语法规则一样,语法格式不一样
break n 退出n层循环
continue n 跳过n层循环,执行下一次循环