CLI
GUI: graphical user interface
CLI:Command-line interface
Shell: A user interface to an operating system(提供了访问操作系统的命令)
0. 前言
0.1 执行命令输出字符串
echo Hello word # echo 用于命令行输出
#hw方式一
vim ~/.bashrc # 文件中存放命令的函数或者调用
当添加:
function h1(){
echo hello word
} 之后;
source ~/.bashrc # 重新执行刚修改的初始化文件
. ~/.bashrc # 效果和source一样
直接使用
h1
>>> hello word
#hw方式二
新建一个文件
vim ./h2
文件中写:
#!bin/bash #指定文件用什么方式执行,可以时python等
echo hello word
结束
echo $PATH #在系统中查看环境变量
export PATH="$PWD:$PATH" #把当前的位置加入环境变量中
chmod +x h2 # 此时h2没有执行权限,修改文件权限,chmod +x 是给执行权限,三个组都给
h2
>>> hello word
#如果不添加文件路径到系统环境中,则执行:
./h2 #指定路径运行脚本
#删除.bashsc 中的 h1
unset h1
其他linux命令:
whereis 的查找面比which 广泛, which 只查找系统目录PATH下存在的;
whereis h2 #找到命令的文件位置
type h1 # >>> h1 is a function 用来判断一个命令是什么,以及位置
man echo # manual 手册的缩写;
tldr echo # too long, don't read;
命令使用:
command options parameters # 命令, 选项中,-都是缩写,--都是单词;参数为文件或者目录或者字符串等。
command subcommand options parameters # 有些比较复杂的如git的命令会使用这种格式
0.2 支持自定义名字
方式1:
# 在.bashrc中的函数:
function h1(){
name_coming=$1
echo hello $name_coming
}
# linux中:
source ~/.bashrc
h1 www
>>> hello www
方式二:
#在文件h2中:
#!/bin/bash
name_coming=$1
echo hello $name_comming
问题: 当输入参数是两个是,只显示第一个
修改为: name_coming=$*
或者 name_coming=$@
* 和 @ 的区别:
不用双引号时,没有区别;
使用双引号: * 表示把所有的参数都组合视为一个参数;
如: h2 1 2, for 输出为 1 2 (不换行)
@ 表示依然时每个独立的参数,用空格分开;
如: h2 1 2, for 输出为 1 换行, 2
在使用for循环时可以看到区别
0.3 显示时间戳
date # 可以显示时间
>>>Tue Feb 22 09:39:03 CST 2022
date "+%Y-%m-%d %H:%M:%S"
echo -n #可以把这一行的空格去掉
$(命令) # 会将命令执行的结果输出 (也可以使用``,一样的效果,但不推荐)
# 修改h2 文件:
#!/bin/bash
TS=$(date "+%Y-%m-%d %H:%M:%S")
name_coming=$@
echo "[$TS] hello $name_coming"
0.4 通过文件显示昵称
文件: name.list
a first_guy
b second_guy
c third_guy
grep 字符串 文件 # 搜索文件中的字符串
grep 字符串 路径 # 也可以是在路径中搜索有字符串名的文件夹
#在上例中,
grep a name.list
>>> a first_guy # 可以获取到一行
cut命令在一个文件中,以行为单位,把每一行选择出来的内容一并输出
-d 选择分隔符,默认table;
-f 选择分割后的哪个区域;
-c 输入每行第n个字符 ,也可以使用 3-6 的形式展示;
cut -d " " -f 2 name.list #之后显示:
first_guy
second_guy
third_guy
h2 修改为:
#!/bin/bash
TS=$(date "+%Y-%m-%d %H:%M:%S")
ID=$1
name=$(grep $ID name.list | cut -d " " -f 2)
echo "[$TS] hello $name"
如果写脚本出错误,如果不让错误信息报出,
name=$(grep $ID name.list 2>/dev/null | cut....)
#要让不存在的用户直接输入unknow:加到echo前
if [[ ""=="$name" ]] #注意: []里面的东西要有看空格,否则报错
then
name="unknown"
fi
关于错误重定向: redirection, 用> 来表示重定向到的位置
dev/null 是一个日志黑洞,所有不想要的东西都可以输出到这里;
STDIN(0) 程序 -> STDOUT (1)标准输出
-> STDOUT (2) 标准错误
把标准错误2 输出到dev/null ,不让它输出到屏幕上
date > date.log #date输出到log文件
date >> date.log #追加到log文件中,不覆盖
#把一个不存在的命令输入的错误信息输出到log文件中:
abc 2> error.log #在屏幕上看不到,因为输出是2, 把2重定向到了log中
把1和2都放到log中去:
h2 a >h2.log 2>&1 # 第一个>,把1放入log;第二个>,把2放入1中,但1会被认为是一个文件,所以添加&
h2 a >h2.log 2>error.log #可以把准确和错误信息分开放
< : 为从输入中读入
cut -d " " -f 2 < name.list # 从标准输入中读取数据,STDIN中读入了name.list; 虽然效果一样,但原理不一样
重定向总结:
- 关于创建: > 为创建和覆盖重定向到的文件, >> 为创建和追加;
-
> 和>>
都是重定向STDOUT, 1为标准输出,2为标准错误, < 也可以用来重定向; - 把1和2 输出到同一文件是,先输出1, 再把2指向1,顺序不能错;1>, 这个中间不能有空格
0.5 管道
ps aux | grep ^root #展示以root开头的所有进程(RE)
ps aux | grep ^root | less -N #用less看,并展示数量
ps aux | grep ^root | wc -l#显示所有的行数 word count
ps aux | grep ^root | wc 显示行数,单词树,字母数
history | sed -E 's/^ + //' | head -3#去掉前面自己补充的“ ”,
history | sed -E 's/^ + //' | cut -d " " -f 3|sort |uniq -c | sort -n #使用uniq可以数数,-c是对字符数数,但必须是先排序的, 数完数后再进行排序
0.6 别名
alias g="git"
alias ipi="ipconfig getifaddr en0"
快捷键: 常用命令
0.RE
1. 变量、引号
var=1
echo '$var'
>>> $var # 单引号只是作为一个字符串输出,忽略其中的字符含义
echo "$var"
>>> 1 # 双引号会解析内部字符的含义,如果要忽略字符含义,则需要\来转义
echo "\$var"
>>> $var
#通常使用本身用单引号,使用它的值用$
变量的扩展:
# 基本使用
variable="some thing"
echo ${variable}
# 替换一部分
echo ${variable/some/a}
>>> a thing
# 取出某一部分
length=7
echo ${variable:0:length}
>>>some th
echo ${variable:-5} #倒取数
# 获取字符串长度
echo ${#variable}
>>> 10
#简介获取:理解为: 指向指针的指针
othervar="variable"
echo ${!othervar}
>>> some thing
#如果变量名的值为空,则返回默认值:
echo ${variable0:-"default value"}#当变量variable0为空,为“”时,返回默认值
>>> default value
variable0="not default"
echo ${variable0:-"default value"}
>>> not default
2. 数组操作
#定义数组
array=(one two three four five six)
#访问第一个元素
echo $array
>>>"one"
echo ${array[0]}
>>>"one"
#访问所有元素
echo ${array[@]}
>>>one two three four five six
# 数组个数
echo ${#array[@]}
>>>6
#数组下标为2的元素的字符个数
echo ${#array[2]}
>>>5
#打印从3开始的两个元素
echo ${array[@]:3:2}
>>>four five
#d打印所有元素,
for i in "${array[@]}";do echo "$i";done