catalog
- WIndows与Unix基本命令
- Bat文件
-
- 规范
- 注释
- Windows-CMD
-
- 介绍
- 管道`|`, 重定向`> <`
- 相对位置
- fc
- 创建文件
- 删除文件/文件夹
- 创建文件夹
- 输出文件内容
- 中文乱码 CHCP
- vim
-
- 缩进
- 查找
- 显示行号
- 删除
- 视图跳转
- 复制
- Deprecated
- tmux
-
- 复制粘贴
- tmux
- ctrl d
- ctrl a, d
- tmux a
- tmux a, s
- tmux a, shift 5
- tmux a, shift "
- tmux a, z
- Deprecated
- Sh脚本文件
-
- 创建一个sh文件
- 命名行参数
- linux命令
-
- 查看文件信息
- sh文件示例
- `expr`四则运算
- 注释
- 声明字符串常量
-
- 访问
- 长度
- `$()` 重定向(标准输出)
- 字符串切割
- linux命令 与 shell命令
- echo 标准输出
- sort排序
- 输出文件内容
- 写入并覆盖文件
- 读出文件并写入另一个文件
- (命令行参数) 和 (标准输入), 管道
- `> 和 >>` 重定向(文件)
- `<` 将(文件) 流入 (标准输入)
- `xargs` 重定向(标准输入)
- 管道`|` 将 (标准输出) 重定向 (标准输入)
- 查找文件/目录
- 查找文件内容
- 历史命令
- 下载工具
- sh文件
- 选择、复制、粘贴
- source引入头文件
- 重定向
- 函数
- for/while循环/continue
- #! /bin/bash
- chmod
- 条件if
- expr
-
- length
- 四则运算
- 比较
- 字符串,变量
-
- 只读变量
- 全局变量
- 打印
- 取字符串/数组 的长度
- 脚本参数
- 进程id
- 获取(命令)返回值
- 数组
- linux文件系统
- 命令
-
- 进程
- ctrl c/d
- seq
- read/echo
- data
- bash
- touch
- ls
- cp
- mkdir
- mv
- cat
- rm
- history
- tmux
- vim
- Linux命令
-
- rm
- file
- arch
- 管道
- 环境变量
-
- 修改环境变量
- PATH环境变量
- LD_LIBRARY_PATH
- C_INCLUDE_PATH, CPLUS_INCLUDE_PATH
- PYTHONPATH
- JAVA_HOME, CLASSPATH
- 常用命令
-
- top
- df
- free
- du
- ps
- kill
- netstat
- w
- ping
- ls
- chmod
- find
- grep
- ag
- wc
- tree
- xargs
- more
- head, tail
- history
- md5sum
- tar
- sudo
- apt-get
- pip
WIndows与Unix基本命令
分类 | Windows 系统 | Unix 系统 |
文件列表 | dir | ls |
切换目录 | cd | cd |
建立目录 | md | mkdir |
删除目录 | rd | rmdir |
比较文件 | fc | diff |
复制文件 | copy | cp |
移动文件 | move | mv |
文件改名 | ren | mv |
删除文件 | del | rm |
Bat文件
规范
开头写成: @echo off
, 就像sh文件的开头#! /bin/bash
echo off
是: 下面的命令, 不展示在命令行中; @
在一个命令前: 该命令不展示在命令行
注释
:: hhh
Windows-CMD
介绍
Windows 自带的命令行界面有两个。
- “命令提示符”(cmd)是其中较为古老的一个,功能也相对简单。
- PowerShell 是较新的一个命令行界面,自带的功能丰富,但相对臃肿。
两个界面都可以在开始菜单中找到。
管道|
, 重定向> <
详见 下面的Linux, 一样的
相对位置
Windows下, 与 Linux, 在处理绝对位置时, 是非常非常不同的!!!
Linux下, 需要是: ./a.exe
而在Windows下, 必须是: a.exe
,
因此: 在Linux下是: system( "./go.exe")
, 而在Windows下必须是: system( "go.exe")
fc
fc a.out b.out
比较两个文件的差异
创建文件
echo > a.txt
删除文件/文件夹
del a.txt
del dir
创建文件夹
mkdir dir
输出文件内容
type a.txt
中文乱码 CHCP
数据,存在计算机上的二进制,是已经确定了!!! (毕竟,一个exe已经生成了)
关键是,如何去解析 这些(二进制)!!! 以什么编码方式,去解析。
CHCP // 获取当前代码页
CHCP 65001 ' utf-8 '
CHCP 936 ' gb2312 '
vim
缩进
按v
选中一些行后, ( 按shift + >
是向右缩进) ( 按shift + <
是向左缩进)
查找
/abc
查看所有的含abc
的位置
显示行号
:set nu
显示行号
:set nonu
不显示行号
删除
ggdG
删除
视图跳转
x G
: 视图回到 (第x行)
G
: 视图到 (最后一行)
x 回车
: 视图往下移动 (x行)
page up
或 page down
: 视图移动
复制
: v
: 按v
进入选中模式, 然后选中后, 按y
: p
粘贴
: dd
剪切一行
:set paste
进入复制模式, 复制完后: : set nopaste
Deprecated
`ggdG` 剪切所有内容
gg=G ' 格式化代码 '
u ' 撤销 '
v ' 然后, 按方向键, 进行文本的选中 '
y ' 复制 所选中的内容. y是yank复制 (无法复制出来, 即仅限于vim里)'
yy ' 复制一行 '
p ' 粘贴 paste '
:set paste ' 当你要shift+insert, 往vim里 粘贴进一些文本时, 要设置这个模式; 否则你的文本, 和他原来的格式 不一样 '
:set nopaste ' 绝大多数下, 都是使用这个模式 (默认vim也是这个模式); 只有当你要粘贴时, 设置paste, 粘贴完毕, 就设置回去nopaste '
/abc '查找 找所有`abc`字符串(按“回车”后,按`n` 可以进行迭代) '
int x;
a
b
当你在;
的后面, 按下回车时, 你肯定是希望光标在a 处
这就是nopaste
模式, 即他会自动给你缩进
但是, 当你要粘贴文本时, 你肯定不希望, 在你文本中的 每个’\n’后面, 都新加一个tab缩进
. 即让文本按照本来的样子来粘贴, 这就是paste模式
tmux
复制粘贴
ctrl a, [
进入(复制模式), (然后你点击左键, 按住, 一旦松开, 就表示复制了)
ctrl a, ]
粘贴
(只在tmux里有效), 在外界不可以; (在外界, 使用ctrl+v
也不行, 即, 他和本机电脑的粘贴板无关, 但ctrl insert
会进入电脑粘贴板)
tmux
如果是在(非tmux)模式下, 则开始一个新的tmux
ctrl d
如果是在(tmux)模式下, 则 (退出) 并 (删除) 该tmux
ctrl a, d
如果是在(tmux)模式下, 则 (退出) 并 (挂起) 该tmux
tmux a
如果是在(非tmux)模式下, 则 进入 (被挂起了的) tmux
tmux a, s
如果是在(tmux)模式下, 则 展示所有的tmux目录
tmux a, shift 5
如果是在(tmux)模式下, 则 在(右侧) 产生一个 新的分屏tmux
tmux a, shift "
如果是在(tmux)模式下, 则 在(下侧) 产生一个 新的分屏tmux
tmux a, z
如果是在(tmux)模式下, 将当前的分屏tmux, 全屏展示 或 取消全屏展示
Deprecated
tmux ' 打开一个新的tmux '
tmux a ' 打开之前挂起的tmux (即恢复你之前的那些分屏状态) '
ctrl + a, shift + 5 ' 左右分屏 '
ctrl + a, shift + " ' 上下分屏 (注意, 是引号键)'
ctrl + a, 方向键 ' 切换视图 '
ctrl + d ' 删除tmux, 退出; '
ctrl + a, d ' 挂起tmux, 退出; [ctrl+d, a]是保存tmux 退出, 然后[tmux a]是恢复之前的tmux状态 '
'比如你当前有很多的分屏, 你想要保存下来, 明天继续 '
ctrl + a, s ' 查看所有挂起的tmux (即被ctrl+d的) '
然后, 选中某个, 按x y ' 删除某个tmux; 按下x, 下面命令行会提示 是否删除'
ctrl + a, z ' 全屏/取消全屏 '
直接鼠标左击选中(复制)
ctrl + a, ] ' 粘贴, 但只能在tmux里粘贴 '
按住shift选中, ctrl+insert ' 也会选中其他tmux, 最好提前给ctrl+a,z 全屏'
shift + insert ' 粘贴 '
Sh脚本文件
以下的内容, 不仅适用于Sh
文件, 也可以直接在shell
里直接录入 其实是一样的, 因为sh
文件里的内容, 就是在shell
里执行的
创建一个sh文件
- 第一步 在文件里开头输入:
#! /bin/bash
一个sh
文件, 必须开头写上这句话; 否则, 你执行./xx.sh
时, 没有 (自动补全)的功能 - 第二步 对该文件
chmod +x xx.sh
给予(执行权限), 否则./xx.sh
执行不了
命名行参数
当执行脚本时: ./xx.sh aa bb cc
在sh文件里面, 通过${1}
就得到第一个命名行参数 aa
; ${0}
是: ./xx.sh
, 即对应的下标为: 0 1 2 3
即, 可以看做是: 有名称为0 1 2 3 ...
的 常量
通过$#
, 可以得到 (最大的下标值), 即上面的3
linux命令
查看文件信息
ldd main.exe
查看这个程序, 链接了哪些DLL
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff9462f0000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff944490000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ff944050000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff944850000)
libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x62860000)
libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x63240000)
libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x64940000)
nm main.exe
查看(符号表所有的全局变量/函数
) (由于符号太多, 一般是: nm main.exe | grep xx
) (符号表, 是在exe里的!!! 而符号表很大的, 一般上线的程序, 会将这个符号表 从exe里删除掉) (比如, exe的大小是54Kb
; 删除(符号表)后, exe的大小是: 16Kb
) strip main.exe
删除掉(符号表) 此时, exe的大小 就变小了; 再使用(nm main.exe)就没有符号表了
file main.exe
查看(文件信息)
size main.exe
查看程序的各个段
text data bss dec hex filename
9916 2348 2432 14696 3968 main.exe
sh文件示例
len=$(expr ${
#1} - 4) #4为文件的后缀 ".cpp"
name=${1:0:len}
比如, 你输入的是: a.sh abc.cpp
那么, len == 3
, name == abc
expr
四则运算
shell不支持直接, 需要借助expr
expr 5 - 3
, 等价于: expr "5" - "3"
将结果直接输出到 (标准输出)
var=$(expr 5 - 3)
存到常量里
注释
# hhh
声明字符串常量
data=123
注意, =
前后不能有空格
a=123
和 a="123"
是完全一样的!!!
没有(数据类型)的概念, 都是string
字符串类型
而且, 这个字符串, 也就是这个常量, 是const
的!!! 不能修改
a="123"
, 然后a[0]='a'
这是不正确的!!! 最终a
会变成一个(数组)!!! 而不是a23
访问
访问常量: ${a}
; (如果你直接写一个a
, 他和一个名为a
的常量, 没有任何关系!!!)
读取出来的是(原始值), 并不是(字符串)
比如: a="ls /hh/"
然后直接: ${a}
, 这相当于: 你在shell里, 执行了一个ls /hh/
命令!!!
长度
${#var}
, 获取该字符串的长度
$()
将(标准输出)重定向到(常量)
保留你sh文件里, 写了一个ls
那么, 这也就相当于: 你在shell里, 打了一个ls
命令, 即输出到了屏幕上
如果你想将 (该命令的输出), 存放到 (变量)里, 而不是 (屏幕); 则$()
可以重定向
str=$(ls)
: 不会输出到屏幕, 而是存放到了str
里
字符串切割
${str:5:2}
: 对应str[5, 6]
子字符串
linux命令 与 shell命令
ls
是 linux命令
echo
是 shell命令
echo 标准输出
echo "abc" "def"
, 等价于: echo "abc def"
echo
默认是不开启(转义), 即: echo "b\na"
, 这个字符串 是4
个字符: b
\
n
a
echo -e "b\na"
开启转义; 这个字符串, 是3个字符: b
\n
a
sort排序
- 命令行参数: (文件位置)
sort a.txt
: 将文件里的内容, 按行划分, 然后 按照(字符串规则)sort
排序sort a.txt b.txt
: 将这些文件的所有内容, 按行划分, 然后sort
排序 - 标准输入 根据(标准输入)的内容, 进行(按行排序)
echo -e "b\na" | sort
, 得到:a
b
(注意, 必须要-e
对echo
转义)
find . -type f -name "*.txt" | sort
- 首先,
|
前的find
, 会找到所有的txt
文件./new.txt ./d.txt ./c.txt ./b.txt ./a.txt ./a/zz.txt
- 然后, 上面的内容, 本来是要到 (标准输出
屏幕
)的; 通过|
, 他变成了 (标准输入) 给了sort
, 最终sort
排序后, 给到 (屏幕):./a.txt ./a/zz.txt ./b.txt ./c.txt ./d.txt ./new.txt
输出文件内容
cat a.txt
写入并覆盖文件
echo "abc" > a.txt
读出文件并写入另一个文件
cat a.txt b.txt > c.txt
将a.txt 和 b.txt
的内容, 按照顺序即先a.txt, 后b.txt
, 拼接到一起, 写入c.txt
里
(命令行参数) 和 (标准输入), 管道
所谓 (标准 输入/输出), 其中的标准
, 通常是指: (屏幕)
一个命令的 (输入), 分为: (命令行参数) 和 (标准输入)
一个命令, 几乎都支持(命令行参数); 但是, 可能不支持(标准输入)
大多数情况下, 如果(命令行参数)是: 文件位置, 则(标准输入) 就是: 该文件的内容 (说白了, 就是任意的文本)
cat a.txt
, 其中的 a.txt
称为: (命令行参数)
(命令行参数):
- 要么是(显式)调用
cat xx
, 这个xx
, 就是(命令行参数) - 要么是
| xargs
的(隐式)调用,xxx | xargs cat
(假设xxx
的屏幕输出是yyy
), 则他会变成:cat yyy
, 这个yyy
, 也是(命令行参数)
(标准输入): 现在还不是特别了解
他只能是(隐式)调用, 通过(管道); 有些命令, 可能并不支持 (标准输入)
比如,wc -l
(计算文件的行数): 他的(命令行参数)是: 文件位置 wc -l a.txt
(计算a.txt
的行数)
那么, 他的(标准输入)是: 文件的内容
(标准输入), 不能(显式)调用!!! wc -l "abc"
, 其中"abc"
并不是 (标准输入), 这样写, 是错误的;
(标准输入), 只能通过 (管道)的方式;
管道: 将 (标准输出) 转换为 (标准输入)
echo "abc" | xx
, 其中, "abc
这个内容, 本来是要 输出到 (屏幕的) 即, echo "abc"
是个 (标准输出) 现在, 通过|
管道, 这个(标准输出) 会成 (下个指令) 的 (标准输入); xx
他就会 接收到 (内容为: abc
) 的 (标准输入)
同样, cat a.txt | xx
, 其中, xx
会 接收到 (内容为: a.txt文件里的内容
) 的 (标准输入)
比如, wc -l
这个命令, 他的: (命令行参数是: 文件位置) (标准输入是; 文本)
目的是: 输出当前目录下, 所有的txt
文件的 总行数 ___1, wc -l *.txt
(命名行参数) 的方式 ___2, cat *.txt | wc -l
(标准输入) 的方式
> 和 >>
将(标准输出)重定向到(文件)
echo "abc" > a.txt
, echo
的内容, 本来是要往(屏幕)输出的, > 或 >>
将他 (重定向) 到了 (文件)里
>
是 覆盖方式>>
是 追加方式
<
将(文件) 流入 (标准输入)
go.exe < data.in
,
go.exe < data.in > go.out
, 可以复合
xargs
将(标准输入)重定向到(命名行参数)
我们知道, >
符号, 可以 (重定向) 到 (文件)里
但如果我们想 (重定向)到 (命令行参数)呢???
比如, 我们知道, cat
命令, 可以接收 (若干个) (文件位置) 的参数, 比如: cat a.txt b.txt c.txt
但如果, 这个参数非常长, 我们不想每次都去 (手动的) 写这个参数, 而是想: , 每次调用cat
命令, 就去(文件)里, 去读取 (参数)
比如, 我们写入到config.txt
里, 他里面内容是: a.txt b.txt c.txt
我们想要: cat a.txt b.txt c.txt
, 即可以写成: cat config.txt | xargs cat
xxx | xargs a b c d
比如, xxx
会往(屏幕)输出yyy
那么, 以上命令, 会变成: a yyy b c d
- 首先,
xxx
产生的这个(标准输出yyy
), 经过|
后, 会变成: (标准输入)的yyy
xargs
再将 (标准输入)的yyy
, 变成 (命令行参数)的yyy
; 而且这里要注意, 是放到了a
的后面
管道|
将 (标准输出) 重定向 (标准输入)
A.exe | B.exe
这会在内存创建一个管道,然后两个程序被同时启动。程序 A 每次要输出被重定向到这个管道中,而这个管道本身不会存储数据(其实有一个很小的缓冲区)。在 B 读取之前,A 的输出操作会被阻塞,等到 B 把数据读入以后,A 的输出才能继续进行。这样优美地解决了上述的问题,没有磁盘 IO 操作,两份代码同时运行,也没有额外消耗很多的内存储存中间结果。
cat data.in | ./a.exe
, 相当于: ./a.exe < data.in
查找文件/目录
find . -type f -name "*.js"
找所有的*.js
文件
-type f
专指: 文件 -type d
专指: 目录
find . -name '*static*'
: 所有与static
相关的 (文件/目录/…)
如果写成: 'static'
是 文件夹, 不包含文件; 因为, 文件肯定有.
, 所以一定要写*
查找文件内容
ag 'hhh' .
历史命令
ctrl r
进入(搜索模式)
下载工具
Linux系统, 分为2种: (RedHat系列: RedHat
, CentOS
) (Debian系列: Ubuntu
, Debian
)
RedHat用的工具是: yum
Debian用的工具是: apt-get
通过: cat /proc/version
, 可以查看系统版本 Linux version 5.4.0-110-generic (buildd@ubuntu) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #124-Ubuntu SMP Thu Apr 14 19:46:19 UTC 2022
sh文件
linux中常见shell有: sh
bash(sh的加强版, 默认)
shell文件里的代码,都可以直接放到你的命令行里执行!! 一样的,只是写成文件,每次可以自动的执行。
选中、复制、粘贴
在shell里,鼠标操作 或 以往的ctrl+c
是 不可以的, 而且是危险的!!! 如果你正在有个任务进行, ctrl+c会中止任务!!!
- 选中: 按住
shift
,鼠标左击 - 复制:
ctrl + insert
- 粘贴:
shift + insert
source引入头文件
类似于C语言, 我们提前写好一些 代码, 然后其他的sh 就可以直接的引入. (其实和C语言一样, 就是代码文件的展开)
a.sh:
var=123
b.sh:
source /home/acs/a.sh ' source也可以写成: . '
echo ${
var}
终端terminal是一个 (大的 bash脚本文件), 我们登陆时, 他会模式先执行( /home/acs/.bashrc
)里的所有内容
而这个文件, 他并不是一个.sh文件
, 执行权限也没有x
. 即./bashrc
这个命令, 是不可行的.
但是, 这个文件里, 都是shell命令!! (比如, 一些ls, dir, ...
, 都可以在shell执行的)
此时, 就可以使用 (文件内容展开) 这个功能.
即把该文件的内容, 都展开到 (当前terminal)里, 也就是: ==该文件里的代码, 都执行了一遍!!! ==
比如: a.txt里是: dir
./a.txt 是失败的. (他没有+x权限)
source a.txt
就等价于 (执行了dir
), 因为把a.txt
里的内容, 展开到当前命令行里
重定向
linux所有进程, 默认都会打开 3个 文件描述符: (stdin 0
, 从命令行输入) (stdout 1
, 向命令行输出) (stderr 2
, 向命令行输出错误)
dir > a.txt ' 将dir的输出, 以(覆盖方式) 到a.txt里 '
ls >> a.txt ' 将ls的输出, 以(追加append方式) 到a.txt里 '
read var < a.txt ' 从a.txt里, (读一行)!!! 因为, read遇到(\n)就结束 '
函数
func(){
a="abc"
echo "hello ${a}"
}
func ' 函数的调用, 不用写参数 '
func(){
a="abc"
echo ${
a}
return 123 ' shell里的函数, 返回值是(exit code,在[0,255]之间) '
' 一般, 0为表示成功(你不写,默认是他) '
'因为, 没有函数返回值这个概念, 所以, 如果要获取返回值, 你可以规则 用他的stdout(即echo) '
}
output=$(func) ' output == "abc" '
ret=$? ' ret == 123 '
for/while循环/continue
for i in 123 abc 456 ' 类似于c++的 序列化容器 '
do
echo ${
i}
done
-----------------
for i in $(ls) ' 命令的输出 '
do
echo ${
i}
done
--------------------
for i in $(seq 1 10) ' 遍历 [1,...,10] '
do
..
done
----------------
for i in {
1..10} ' 遍历[1,...,10] ;'
for i in {
10..1} ' 遍历[10,9,...,1] '
for i in {
a..z} ' 遍历[a,b,..,z] '
--------------
for ((i=1; i<=10; ++i)) ' 遍历 [1,...,10] '
...
while read a ' 当你ctrl + d时, 就是文件结束符. 即终止录入 '
do
echo ${
a}
done
-------------------------
for ((i=1; i<=10; ++i))
do
if [ $( expr ${
i} % 2 ) -eq 0 ] ' 跳过所有的 偶数 '
then
continue
fi
echo ${
i}
done
#! /bin/bash
开头 必须要写上: #! /bin/bash
,这是在指明(使用bash作为 脚本解释器)
chmod
chmod: change mode 改变模式
一个执行文件`a.sh`,需要有(执行的权限): `chmod +x a.sh`
条件if
if [ ${
a} -lt ${
b} ]
then ' 注意这里有个then, 其实就表示: 如果这个if成立,则... '
echo "a < b"
else
echo "a >= b"
fi
if ! [ ${
a} -eq ${
b} ] ' 取反: ! '
then
echo ""
if
if [ .. ]
then
...
elif [...]
then ' 注意格式!! '
...
else
...
fi
expr
length
expr length "${var}"
,求一个字符串的长度 (加""
,是处理 var里有空格的情况)
四则运算
v1=123
v2=456
echo ${
v1+v2} ' 输出是出错的! '
shell是不支持运算的!!
v1=123
v2=456
echo $(expr ${
v1} + ${
v2}) ' 注意, +的左右 要有空格!! '
echo $(expr ${
v1} - ${
v2}) ' -号,左右要有空格! '
echo $(expr \( ${
v1} + 1 \) \* ${
v2}) ' *号要转义(\*)!! 括号也要转义!! '
比较
v1=123
v2=456
echo $(expr ${
v1} '==' ${
v2}) ' 判断是否相等 (注意,要用单引号括起来) '
echo $(expr ${
v1} '<' ${
v2})
字符串、变量
var="abc"
var='abc'
var=abc
三种写法都可以,注意:等号左右,不可以有空格!! (''
写法,不会转义!! ""
写法,会进行转义!)
shell里不存在(数据类型)的概念,即都是“字符串”!! (但他会自动检测,当需要是整数时,他会自动转换)
shell里的变量, 不存在 (定义)这个含义. 比如你 echo ${a}
, 即使他不存在, 也不会报错, 他的值是空的.
var="abc ef"
echo ${
var}
这是会报错的!!! 但是,并不是说,var不能存储空格! 而是,${var}
操作 其实就会变成:abc ef
!!!
即,其实是形如: echo abc ef
,这是报错的!!
所以,在对字符串进行操作时, 最好要加上 ""
(可以处理,有空格的情况)
即,echo "${var}"
,这就对了
只读变量
var="abc"
readonly var
var
只读,不可以修改
全局变量
export var
: 所谓“全局”,指的是 “进程”!! 即,当前进程的 子进程,可以访问到(当前进程里的var
)
export var=123
: 声明一个全局变量
打印
echo
输出到屏幕
取字符串/数组 的长度
var="abc"
echo ${
#var} ' 会输出: 3 '
脚本参数
echo ${
0}
echo ${
1}
echo ${
2}
echo ${
3}
当执行:./a.sh 1 2 3
,会输出: ./a.sh 1 2 3
当执行:/home/wc/a.sh 1 2 3
,会输出:/home/wc/a.sh 1 2 3
(即,你命令行是怎么执行的这个sh文件, 就对应几个参数)
echo $#
,表示,你传入的(参数个数)输出参数个数(不包括第一个参数) (比如上面命令, 你传入了:1, 2, 3
共3个)
进程id
$$
当前进程id
获取(命令)返回值
echo $(ls) 等价于 echo `ls` ' 输出: ls的结果 '
注意,是$()
,不是${}
数组
arr=(123 "abc")
以上写法,完全等价于:
arr[0]=123
arr[1]="abc"
--------------------------
获取元素: ${
arr[0]}
---------------------------
arr[0]=1
arr[5]=5
arr[10]=10
${
arr[*]} ' 所有元素: 1 5 10 '
${
#arr[*]} ' 数组长度: 3 '
可以发现,shell里的数组,有点像是: map的