shell/bash其实就是我们日常在unix系统终端中执行的语句,只是通常我们在命令行中都是单行语句执行的,而有时,我们希望将一些操作命令写到一个文本中,让电脑自动按顺序或是并行地执行这些命令,这样我们就不需要时刻守在电脑前一行行去执行命令了。
  

1 文件构成

1.1 文件后缀

  shell文件通常以.sh为后缀,如test.sh,其实质是一个文本文件。
  

1.2 指定解析器

  通常,文件的第一行是该文件所需要使用的解析器的定义,一般使用bash,命令如下:

#!/bin/bash

  

1.3 运行脚本

  比如要运行名为test.sh的脚本文件,首先我们先将命令行路径进入到该脚本文件所在路径下,有三种形式(任选其一即可):

./test.sh        # 先按照文件中#!指定的解析器解析
bash test.sh     # 先用bash解析器解析
. test.sh        # 直接使用默认解析器解析

  在运行的时候,可能你会遇到如下报错:

-bash: ./test.sh: Permission denied

  说明test.sh文件还没有执行权限,我们通过命令行给它加上执行权限:

chmod +x test.sh

  之后再运行test.sh文件就可以了。
  

2 常用命令

2.1 注释 -

  单行注释与python语言的一致,由单个#开始。
  

2.2 输出 - scho

  语法格式:

echo hello world

  上面都没有给出运行示例,现在,让我们打开新建的test.sh文件,在里面输入如下内容:

  然后打开命令行,执行文件,就可以看到输出了:

  

2.3 变量定义与使用

  shell里的变量不需要指明变量类型,类似于python,可以直接进行声明和赋值。比如:

myage=18    # 声明一个变量myage,值为20

  但是,需要注意如下两点:

  1. 等号前后是没有空格的
  2. 变量没有类型之分,都默认为string类型,即myage=18myage=“18”在使用的时候都是一样的

  变量的使用方式有两种:

  1. 直接$变量名
  2. ${变量名}

  这两种方式都是可以的,第2种方式在变量名前后加上{},主要是可以界定变量名的范围。比如使用上面定义的变量:

echo I am ${myage}years old
# 输出为I am 18years old

  但是如果没有使用花括号:

echo I am $myageyears old
# 输出为I am old

  

2.4 扩展计算 - (())

  (( ))是一种扩展运算符,只要符合C语言标准的语句都可以在这里面执行。比如使用上面定义的myage变量,现在我要让它自增1。如果直接写:

myage+=1
# 输出myage,会发现结果是181,也就是被当成字符串运算了

  而要获得正确结果,应该写成:

((myage++))
((myage+=1))
# 以上两种写法都可以,结果均为19

  需要注意的一点是,shell只能作整数运算,对于浮点数都是直接当作字符串处理的。
  此外,除了(( ))之外,shell中还有( )[ ][[ ]]等等括号,用法不尽相同,可以参考:shell中各种括号的作用()、(())、[]、[[]]、{}
  

2.5 多语句同行 - ;

  要将多个不同的语句放在同一行,需要在语句末加上;进行分隔。比如:

myage=18; echo I am ${myage}years old

  

2.6 续行 - \

  如果一个语句太长了影响阅读,可以通过\将一行语句写为多行。比如:

python test.py --config config.txt \--input data.txt \--output output.txt

  这是一个运行python文件的命令,这里将其分为三行。注意这里续行符的左边都有一个空格,这样的话这三行命令就等同于如下一行命令了:

python test.py --config config.txt --input data.txt --output output.txt

  也即不同参数之间存在一个空格。如果没有了续行符左侧的空格,就会等同于:

python test.py --config config.txt--input data.txt--output output.txt

  这里,续行符左侧的每个空格和实际空格是一一对应的,如果有两个空格,那将命令放在一行的时候也是两个空格。但是续行符右侧的空格数量和换行之后命令前的空格数量都是不影响命令的,比如:

python test.py --config config.txt \
--input data.txt \
--output output.txt

  这样写命令也是可以的。
  

2.7 循环 - for

  for循环的一般格式为:

for var in item1 item2 ... itemN
docommand1command2...commandN
done

  如果要将其写成一行,则是:

for var in item1 item2 ... itemN; do command1; command2… done;

  比如:

for loop in 1 2 3 4 5
doecho "The value is: $loop"
done

  输出结果为:

The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

  除了这种方式外,类似于C语言的for循环也是可以的,比如:

for((i=1;i<=5;i++))
do
{echo $i
}
done

  输出的结果为:

1
2
3
4
5

  需要注意的是,这里for循环需要两个小括号(扩展C语言计算),不能将其中一个去掉,否则会报语法错误。
  

2.8 选择 - if-else

  一般格式为:

if condition1
thencommand1
elif condition2
then command2
elsecommandN
fi

  其中最后的fiif语句结束的标记,elifelse都是可选的。
  一个例子:

a=10
b=20
if (( $a == $b ))
thenecho "a 等于 b"
elif (( $a > $b ))
thenecho "a 大于 b"
elif (( $a < $b ))
thenecho "a 小于 b"
elseecho "没有符合的条件"
fi

  输出为:

a 小于 b

  

2.9 并行执行 - &

  shell脚本默认是串行执行命令的,也就是只有当上一行语句运行完成后才会运行下一行命令。但是有时候,我们希望命令是一起执行的。比如,我的服务器上有多张GPU,想在每张GPU上都跑不同的任务,它们之间互不相干,因此可以同步执行。并行执行的方法也很简单,就是直接在上一行命令的末尾加上&符号即可。比如:

python test1.py&
python test2.py&
python test3.py

  如果使用for循环,也可以简单地写为:

for((i=1;i<=3;i++))
do
{python test${i}.py
};
done

  

2.10 等待 - wait

  使用&运算符可以使命令同步执行,但是有时,下一步的程序是需要依靠上一步的执行结果来作为输入的。那么,我们需要确保上一步完全执行完毕了,才运行下一步的命令。这时,我们可以使用wait关键字。比如:

python test1.py
wait
python test2.py

  这样,就只能在test1完成后,才会执行test2任务了。
  

2.11 暂停 - sleep

  sleep命令可以使命令行暂停一定时间再执行。比如:

python test1.py
sleep 10
python test2.py

  这样,test1执行完之后,会等待10s,之后才执行test2。

shell/bash命令还有丰富的语法内容,这里只列出一些基本的命令,可以供日常简单的使用。如果还需要更复杂高级的应用,可以寻找专业的资料进一步学习。

  

3 一个实例

  根据上述内容,我写出了如下脚本文件,该文件用于运行mega-nerf网络中。

#!/bin/bash##################################################### variables ######################################################### experiment id
expid=14# colmap sparse model path, where contain cameras,images,points3D
modelpath=../../data166/ISPRS1/ISPRS1/rescale_2/sparse
# input scene images path
imagespath=../../data166/ISPRS1/ISPRS1/rescale_2/images
# image number for validation
numval=24
# PCA rotation if coordinate is not aligned
pcarotate=--pca_rotate
# output meganerf files path
megapath=../../outdata/isprs/experiment${expid}/isprs_mega
# where contain rayrange message, can be generate automatically
configfile=../../outdata/isprs/experiment${expid}/rayrange.yaml# mask path
maskpath=../../outdata/isprs/experiment${expid}/mask16
# grid dim
griddim1=4
griddim2=4# scale to downsample images
trainscalefactor=2
# experiment prefix(where to store training results)
expprefix=../../outdata/isprs/experiment${expid}/exp
# chunk prefix(where to store chunk message)
chunkprefix=../../outdata/isprs/experiment${expid}/chunk
# where to save log files(with prefix)
logdir=../../outdata/isprs/experiment${expid}/chunks
# depth guide path
depthmappath=../../outdata/depth# checkpoint prefix(where store the network parameters)
ckptprefix=../../outdata/isprs/experiment${expid}/exp-
# centroid path
centroidpath=${maskpath}/params.pt
# to merge the models with how many training iterations
trainiterations=50000
# file path to store merged model
mergedpath=../../outdata/isprs/experiment${expid}/merged${trainiterations}.pt# path to store evaluation results
evalpath=../../outdata/isprs/experiment${expid}/eval
# valuation scale
valscalefactor=8##################################################### commands ########################################################## colmap to meganerf
python scripts/colmap_to_mega_nerf.py \--model_path ${modelpath} \--images_path ${imagespath} \--num_val ${numval} \--output_path ${megapath} \--config ${configfile} \${pcarotate}wait# generate clusters
python scripts/create_cluster_masks.py \--config ${configfile} \--dataset_path ${megapath} \--output ${maskpath} \--grid_dim ${griddim1} ${griddim2}wait# training: run_4
for ((i=0;i<4;i++))
do
{CONFIG_FILE=${configfile} \DATASET_PATH=${megapath} \MASK_PATH=${maskpath} \TRAIN_SCALE_FACTOR=${trainscalefactor} \EXP_PREFIX=${expprefix} \CHUNK_PREFIX=${chunkprefix} \DEPTHMAP_PATH=${depthmappath} \nohup python -m parscript.dispatcher parscripts/run_4_${i}.txt -g 8 > ${logdir}${i}.log 2>&1 &
}&
donewait# merge models
python scripts/merge_submodules.py \--config_file ${configfile} \--ckpt_prefix ${ckptprefix} \--centroid_path ${centroidpath} \--train_iterations ${trainiterations} \--output ${mergedpath}wait# evaluate model
python mega_nerf/eval.py \--config_file ${configfile} \--exp_name ${evalpath} \--dataset_path ${megapath} \--container_path ${mergedpath} \--val_scale_factor ${valscalefactor}

  
部分内容参考:
shell脚本的使用入门(超全)
Shell 流程控制

shell/bash脚本命令教程相关推荐

  1. 一个很不错的bash脚本编写教程

    一个很不错的bash脚本编写教程 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bash (bourne again shell) 进行shell编程,因为bash是免费的并且很 ...

  2. shell bash脚本_如何在Windows 10上创建和运行Bash Shell脚本

    shell bash脚本 With the arrival of Windows 10's Bash shell, you can now create and run Bash shell scri ...

  3. 通过shell/bash脚本使用ffmpeg批量去除视频固定片头和片尾(Cygwin环境)

    通过shell/bash脚本使用ffmpeg批量去除视频固定片头和片尾(Cygwin环境) 任务需求: 基本情况: 技能需求: 操作流程概括: 运行通过的shell脚本: 小结 任务需求: 对一批视频 ...

  4. Shell红客脚本命令

    Shell红客脚本命令 一.基本Shell命令 二.运行Shell脚本的方法 三.特殊符号Shell命令 四. shell注释 五.shell变量 六. Shell命令printf命令 七.shell ...

  5. linux shell运行脚本命令行参数,shell脚本命令行参数简介

    之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互. bash shell提供了命令行参数添加在命令后面的数据值).命令行选项修改命令行为的单字符值)和直接读取键盘输入. 1.命 ...

  6. bash脚本编写教程

    这部教程是我在网上找到比较经典的BASH中文教程,对新手学习bash脚本,bash编程的好文章. 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bash (bourne agai ...

  7. 反弹shell bash -i命令

    目录   0x01 什么是反弹shell?   0x02 命令拆分详解   0x03 文件描述符   0x04 shell 输入/输出重定向   0x05 输入输出结合获得shell 什么是反弹she ...

  8. shell bash常用工具教程(curl,jq)

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 curl curl -h来查看请求参数的含义 -v 显示请求的信息 -X 选项指定其它协议 get:curl -v 192.168.33.1:8080 ...

  9. 用管道pipe实现程序与shell/bash脚本之间的通路

    文章GitHub源码地址:https://github.com/Rtoax/test/tree/master/ipc/pipe-exec 目录 代码架构 源代码 makefile mycmd.sh p ...

最新文章

  1. cannot find module 'cordova-common'
  2. svn命令行使用说明
  3. java transient_【转】Java中的关键字 transient
  4. 高并发负载均衡(二):LVS 的 DR,TUN,NAT 网络模型推导
  5. 全志r11_全志R328 Demo开发板;全志R333开发板/核心板;全志R11开发板/核心板;全志R16开发板/方案设计...
  6. C语言bcd码减法过程,bcd码的减法运算规则举例.ppt
  7. jstack 线程状态分析_面试官:说说你是怎么用JDK监控和故障处理工具的吧?例如jstack...
  8. java帳戶登錄_java.sql.SQLException: ORA-28000: 帐户已被锁定
  9. linux系统可以装sas吗,在SAS硬盘上Linux安装注意的事情。
  10. MATLAB实现多元正态Copula分布
  11. 最简单的DLL导出函数隐藏方式
  12. 户外运动手持GPS设备常识汇总
  13. 过渡属性transition详解
  14. 网页中视频在线播放脚本
  15. 配置全局less变量;解决iphoneX、 iphone8 plus 键盘退下去仍占空间,导致无法点击;vue-photo-preview 配置正常,但无法触发图片的预览
  16. 使用免费小图标(趣味)
  17. 扛过字节Java研发岗4轮面试,收到sp offer(月薪35k)!揭秘字节面试流程及考题(附带答案)
  18. Python开发环境安装及Project interpreter not specified问题解决
  19. C++批量修改文件后缀名(提供多种方法)
  20. .NET/C# 生成二维码

热门文章

  1. android自动显示金额UI,Android UI中英文自动显示问题
  2. UNITY 2D学习笔记(二):C#脚本编写
  3. php仿信用卡积分商城,php实现通用的信用卡验证类
  4. ssm+jsp计算机毕业设计中医养生客户管理系统c3z16(程序+lw+源码+远程部署)
  5. android210的启动logo的修改
  6. springboot整合swagger+knife4j
  7. 秒杀商品超卖了,差点被辞退...
  8. 美团月付逾期一天对征信有没有影响?
  9. 2021 KDD投稿时间
  10. 低层次的努力,注定你过不好这一生