注
基本使用过ubuntu的命令行,但是不是很熟悉
一下全以我的认识路线角度叙述
开头
#!/bin/bash
表示这个文件用bash运行,其他因为暂时用的不多,不提
到时候运行就是去终端里:
bash <your_file.sh>
开启多个终端
#!/bin/bash
gnome-terminal --tab -- bash -c "source devel/setup.bash;roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch"
sleep 20s
gnome-terminal --tab -- bash -c "source devel/setup.bash;roslaunch mbot_navigation nav_cloister_demo.launch"
以这个例子,比较注意的是 -- bash 是 --空格bash,然后按这个模板把要运行的命令加入到双引号里,我试了一下也算freeform?
#!/bin/bash
gnome-terminal --tab -- bash -c "mkdir test_sh;
cd test_sh;
touch test.txt;
echo this is the first try! > test.txt;
sleep 100"
gnome-terminal --tab -- bash -c "mkdir test2_sh"
这样不可以
#!/bin/bash
gnome-terminal --tab -- bash -c
"mkdir test_sh;
cd test_sh;
touch test.txt;
echo this is the first try! > test.txt;
sleep 100"
gnome-terminal --tab -- bash -c "mkdir test2_sh"
使用sudo
使用sudo如何输密码呢
可以加一个 -S 参数,表示密码不从命令行输入,从“标准输入中读取密码”(不太理解这句话),但是确实从脚本读入的
#!/bin/bash
sudo -S pip install numpy << T
<your_passward>
T
其中的 T 是一个标识符,只要保证开头和结尾是一致的就行,一般使用“EOF”作为标识符 ,我使用T是为了尝试一下
注意:-大写S,<<小于号
什么是bash,什么是shell
从这里开始,我们后面就不再说写.sh文件了,而是写bash,.sh是一种脚本文件在unix系统是shell脚本文件,通常使用bash作为解释器
我们这个博客应该叫 shell编程合适一些
#!/bin/sh
cd ~
mkdir shell_tut
cd shell_tut
for ((i=0; i<10; i++)); do
touch test_$i.txt
done
看个例子,第二行中~是home路径的意思,for循环中使用变量 加$ 有时候也会加{}来更明显的确定变量的边界
这个脚本就是创建了txt文件后缀从0到10个
而且同样的脚本语言还有python等高级语言,但是什么语言做什么事情,只是一些简单的安装,备份,下载数据的事情,完全可以使用bash写一个sh文件,不会太复杂
编写
#!/bin/bash
#! /bin/php
"#!"就是一个约定,约定使用哪种解释器
运行
其一
./<file.sh>
像这种二进制文件一般系统都会到/bin, /sbin, /usr/bin,/usr/sbin这些PATH里的路径去找,你写的.sh文件肯定会找不到,所以就要加./来说明是在本目录下去找
其二
bash <file.sh>
sh <file.sh>
但这样脚本第一行#!就白写了
变量
PI=3.1415
file_name="text"
注意:与其他变量定义不一样的是,不能使用空格(强迫症难受)
用语句给变量赋值:
for f in `ls /etc`
#来遍历/etc目录下的文件
for f in $(ls /etc)
注意:不是单引号,而是反引号就是键盘左上角那个~`
举个我写的不好的例子
#!/bin/bash
for f in $(ls /${PWD});do
echo ${f}
done
这里使用ls是不恰当的,因为文件名中可能会包含特殊符号或者空格导致出错,最好应该使用统配符 ./*
do
标志着循环体的开始,即从这里开始执行循环内部的命令。done
标志着循环体的结束。
#!/bin/bash
for f in ./*;
do
echo $f
done
只读变量
a=1
readonly a
删除变量
unset a
变量类型
declare和typeset
用""和‘’包裹起来的都是字符串
declare -i a=12
b="file"
#!/bin/bash
a=(1 2 3 4)
echo $a
#>>> 1
echo ${a[1]}
#>>> 2
类似字典一样的联合数组:
#!/bin/bash
declare -A list
list["name"]="nike"
list["age"]=38
echo ${list["name"]}
出现下图问题,当我用参数—A时联合数组没有任何问题,用-a(数组类型)出现奇怪的问题了,所以我个人推测字符串的值都被系统当作1了
验证想法
输出数组所有元素
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
获取数组所有的建
echo "数组的元素为: ${!my_array[*]}"
echo "数组的元素为: ${!my_array[@]}"
数组长度:
echo "数组的元素为: ${#my_array[*]}"
echo "数组的元素为: ${#my_array[@]}"
获取字符串长度
string="abcd"
echo ${#string} # 输出 4
shell传输参数
#!/bin/bash
echo $1
echo $2
echo $3
echo $@
# bash test.sh 1 2 3
# 1
# 2
# 3
# 1 2 3 4
基本运算符号
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
echo
echo `date`
2024年 04月 27日 星期六 01:03:37 CST
加注释的示例
#! /bin/bash
# 检查"test3"目录是否不存在
if [ ! -e "test3" ]; then
# 如果不存在,则创建"test3"目录
mkdir test3
fi
# 尝试进入"test3"目录,如果失败则退出脚本
cd test3 || exit 0
# 定义文件名前缀
file_name=text
# 初始化文件编号
file_num=1
# 循环三次,创建文件并打印当前循环次数
for i in {1..3}; do
# 创建文件,文件名格式为"text_编号",编号由循环变量$i提供
touch "${file_name}_${i}"
# 打印当前循环次数
echo $i
done
# 循环检查是否存在以当前file_num编号命名的文件
while [ -e ${file_name}_${file_num} ]; do
# 如果文件存在,则递增file_num
((file_num++))
# 这里重新赋值filename变量
filename=${file_name}_$file_num
done
# 打印最终得到的文件名
echo "${filename}"
touch $filename
方括号前后一定加空格
for i in【1..2】无空格
未完代续