Shell常用命令与脚本实例

脚本,Shell,实例,命令 · 浏览次数 : 46

小编点评

# EOF与<<结合 # EOF是(END Of File)的缩写,表示自定义终止符。既然自定义,那么EOF不是固定的,可以随意设置别名,在linux按ctrl-d 就代表EOF。#EOF一般会配合cat能够多行文本输出。#其用法如下: #<<EOF #开始#.... #输入内容#EOF #结束#熟悉几个特殊符号:#<:输入重定向#>:输出重定向#>>:输出重定向,进行追加,不会覆盖之前内容#<<:标准输入来自命令行的一对分隔号的中间内容# :<<COMMENTBLOCK# shell脚本代码段# COMMENTBLOCK# 用来注释整段脚本代码。 :是shell中的空语句。:<<EOFshell 目录,文件判断-f \"file\" : 判断file是否是文件;-d \"file\" : 判断file是否是目录(文件夹)。EOF:<<EOFxargs 将标准输入作为下一条命令的参数$ echo \"hello world\" | xargs echohello world上面的代码将管道左侧的标准输入,转为命令行参数hello world,传给第二个echo命令。EOFif [ $paramNum -lt 2 ]then echo \"请输入查询的字符串与要替换的新字符串\"else if [ $subCmd == $subCmdValue1 ]; then param1=$2 param2=$3 echo \"开始查询:${param1}\" checkFileAndDir ${param1} elif [ $subCmd == $subCmdValue2 ]; then param1=$2 param2=$3 echo \"查询的字符串:${param1},要替换的新字符串:${param2}\" scanDir else param1=$1 param2=$2 echo \"查询的字符串:${param1},要替换的新字符串:${param2}\" scanDir fi fi   。归纳总结以上内容,生成内容时需要带简单的排版

正文

 
#!/bin/sh
  
echo "Hello shell"
  
# ----------------------字符串---------------------#
  
readonly URL="定义一个常量:www.baidu.com"
  
your_name="jack"
echo $your_name
echo ${your_name}
  
  
for file in `ls ~/Desktop`; do
    echo "${file}"
done
  
echo $URL
  
your_name1='单引号字符串内部不能有变量,只能固定输出'
your_name2="单引号字符串可以有变量${URL},和转义符\"Hi,转义\""
echo $your_name1
echo $your_name2
  
echo "字符串长度:${#your_name}"
echo "子字符串,从1下标开始读3个字符:${your_name:1:3}"
echo `gexpr index "$your_name1" 固定` #语法错误
echo "使用#号可以截取指定字符(或者子字符串)右边的所有字符, *表示跨过左侧任意个字符:${your_name1#*固定}"
echo "使用%号可以截取指定字符(或者子字符串)左边的所有字符, *表示跨过右侧任意个字符:${your_name1%固定*}"
  
#字符串转数组
string="hello,shell,split,test"
#将,替换为空格
array=(${string//,/ })
 
#字符串包含判断
#字符串是否符合正则表达式?
if [[ ${1} == *\.podspec || ${1} == *\.pbxproj || ${1} == *\.plist || ${1} == *\.sh ]];
#字符串包含:父字符串$filterList 是否包含子字符串$item ?
if [[ $filterList =~ $item ]]
  
# ----------------------数组---------------------#
 
cities=("北京" "上海" "深圳" "杭州")
echo ${cities[1]}
 
echo ${cities[@]} # @:获取数组中所有的元素
echo ${!cities[@]} # ![@]:获取数组中所有的元素的key键,数组可以放[key:value]对
echo "数组的长度:${#cities[@]}"
 
# 数组包含判断
# 数组包含:数组$"{filterList[@]}" 是否包含字符串"$item" ?
if [[ "${filterList[@]}" =~ "$item" ]]
# 数组不包含?
if [[ ! "${filterList[@]}" =~ "$item" ]]
 
# 数组添加元素
# 添加方式 语法 可添加多个元素 下标必须连续 添加后下标改变 可能覆盖原有元素
# 直接下标添加 cities[index]=value 否 否 否 是
# 数组长度添加 cities[${#cities[@]}]=value或cities[${#cities[*]}]=value 否 是 否 是
# 重新创建数组 cities=("${cities[@]}" value1 ... valueN) 是 否 是 否
# 赋值运算符+= cities+=(value1 ... valueN) 是 是 是 否
:<<EOF
多行注释: 定义一个函数EOF,但是没有地方调用,达到注释的效果
EOF
 
# ----------------------传递参数---------------------#
 
:<<EOF
$0: 执行文件名
$1: 第一个参数
$2: 第一个参数 . .
EOF
 
echo "执行文件的名称为:$0,传参个数为:$#, 参数值为:$1,$2"
 
# ----------------------运算符执行---------------------#
 
需要获取命令结果返回值的使用下面2种方式
纯命令用``或$()执行 `xcodebuild -list -project aaa.xcodeproj`
带参数用$()执行 $(ls $name)
 
不需要获取命令结果返回值的,直接写命令即可
xcodebuild -list -project aaa.xcodeproj
 
# ----------------------函数---------------------#
 
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。
return 后跟数值n(0-255)
3、函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数,超过10个用${11}
 
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
     echo "第十个参数为 $10 !"
     echo "第十个参数为 ${10} !"
     echo "第十一个参数为 ${11} !"
     echo "参数总数有 $# 个!"
     echo "作为一个字符串输出所有参数 $* !"
}
 
funWithParam 1 2 3 4 5 6 7 8 9 34 73
结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
 
# ----------------------逻辑运算---------------------#
 
单中括号[],双中括号[[]],小括号(())的区别?
if [[ $a > $b ]] 双中括号支持正则表达式
if [ $a > $b ] 单中括号不支持正则表达式
if (( a > b )) 小括号不用使用$做取值了
 
 
判断:大于,小于,等于,不等于。
在比较时,数字和字符串可以使用不同的比较符号
比较数字 (numberic):-ne
比较字符 (string):!=
多条件使用|| 或者 &&
 
1.如果a>b且a<c
if [[ $a > $b ]] && [[ $a < $c ]]
或者
if [ $a -gt $b -a $a -lt $c ]
 
if (( a > b ));
then
...
else
# 如果else里没有处理语句,则else不能写
fi
  
if [ $subCmd == $subCmdValue1 ]; then
fi
if [ ${projName} != "Pods" ]; then
fi
  
判断:非空判断 不为空
if空判断
if [ ! -n "$a" ]; then
echo "IS NULL"
else
echo "NOT NULL"
fi
 
if [ ! $a ]; then
echo "IS NULL"
else
echo "NOT NULL"
fi
 
# ----------------------文件目录---------------------#
 
shell 目录,文件判断
-f "file" : 判断file是否是文件;
-d "file" : 判断file是否是目录(文件夹)。
:<<EOF
xargs 将标准输入作为下一条命令的参数 $
echo "hello world" | xargs echo hello world
上面的代码将管道左侧的标准输出,转为命令行参数hello world,传给第二个echo命令。
EOF
 
 # ----------------------循环遍历---------------------#
 
 sortSchemeNames=(aaa bbb ccc)
 projInfo=`xcodebuild -list -project aa.xcodeproj`
 #目标字符串projInfo中,#*中间间隔任意个字符串直到查到“Schemes:”字符串,返回其右侧的部分
 tragetSchemes=${projInfo#*Schemes:}
 for ((i=0; i<${#schemeNames[@]}; i++)); do
    scheme=schemeNames[i]
    # 父字符串$tragetSchemes 是否包含子字符串$scheme ?
    if [[ $tragetSchemes =~ $scheme ]] then
        echo "------------第${i}个库构建开始:${scheme}"
        echo "++++++++++++第${i}个库构建结束:${scheme} \n"
    fi
 done
 
 for scheme in ${sortSchemeNames[@]}; do
    if [[ $tragetSchemes =~ $scheme ]] then
        echo "----------> build 开始:${scheme}"
        echo "<---------- build 结束:${scheme} \n"
    fi
 done
 
 # ----------------------路径截取---------------------#
 
 :<<EOF
 
 shell之文件路径截取 file=/dir1/dir2/dir3/my.file.txt
 我们可以用${ }分别替换获得不同的值:
 
 ${file#*/}:拿掉第一条/及其左边的字串:dir1/dir2/dir3/my.file.txt
 ${file##*/}:拿掉最后一条/及其左边的字串:my.file.txt
 ${file#*.}:拿掉第一个.及其左边的字串:file.txt
 ${file##*.}:拿掉最后一个.及其左边的字串:txt
 ${file%/*}:拿掉最后条/及其右边的字串:/dir1/dir2/dir3
 ${file%%/*}:拿掉第一条/及其右边的字串:(空值)
 ${file%.*}:拿掉最后一个.及其右边的字串:/dir1/dir2/dir3/my.file
 ${file%%.*}:拿掉第一个.及其右边的字串:/dir1/dir2/dir3/my
 
 引用地址:http://www.jb51.net/article/94355.htm
 
 EOF
 
 # ----------------------数学运算---------------------#
整数运算使用:(())
小数运算使用:bc
另外:expr(可用于整数运算,也可以处理字符串。比较麻烦)
 
 
语法格式为:((表达式))
表达式可以只有一个,也可以有多个。如果是多个表达式,那么多个表达式之间以逗号,分隔。它们以最后一个表达式的值作为整个 (( )) 命令的执行结果。可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。
变量赋值: a=$((10+66) b=$((a-15))
逻辑运算: ((a>7 && b==c))
多表达式: ((a=3+5, b=a+10))
在 (( )) 中使用变量无需加上$前缀,(( )) 会自动解析变量名
 
 
bc 是 Linux 下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。
Linux bc 命令的语法格式为:
command "表达式" | bc
 
i=10
echo $i
j=3;
echo $j
 
m=`expr $i / $j`
echo $m
 
n=`echo "scale=9; $i / $j" | bc`
echo $n
scale是指定精度,而且只有在除法的时候才有生效,其他都是安装原来都有几位就输出几位;bc支持除了位操作的所有运算。
 
 
expr 是一款表达式计算工具,可用于整数运算,也可以处理字符串
Shell expr 命令的语法格式为:
$(expr variable + variable) 或者 `expr variable + variable`
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
 
i=10
echo $i
 
i=`expr $i + 10` #20
echo $i
 
 
# 加减乘除运算
# 乘法
r=`expr 4 \* 5`
r=$(( 4 * 5 ))
r=$[ 4 * 5 ]
echo $r
  
# 除法
r=`expr 40 / 5`
r=$(( 40 / 5 ))
r=$[ 40 / 5 ]
echo $r
  
# 减法
r=`expr 40 - 5`
r=$(( 40 - 5 ))
r=$[ 40 - 5 ]
echo $r
  
# 求余数
r=$[ 100 % 43 ]
echo $r
  
# 乘幂 (如 2 的 3 次方)
r=$(( 2 ** 3 ))
r=$[ 2 ** 3 ]
echo $r

 # ----------------------多条命令一起执行---------------------#

“;”隔开,多条指令无论成败,都会执行
cd /home/PyTest/src; python suning.py

“&&”隔开,多条指令前面的成功了后面才执行

“||”隔开,或,多条指令前面的执行失败,后面才执行

“|”隔开,管道符,多条指令无论成败,都会执行

 

脚本案例

批量编译项目Target依赖的所有子Schemes
# 产物默认目录下~/Library/Developer/Xcode/DerivedData/*
# -destination generic/platform=iOS \
# -destination generic/platform=iphonesimulator\
 
plateformDevice='generic/platform=iOS'
plateformSim='generic/platform=iphonesimulator'
 
# 1.获取工程下所有的schemes, 遍历构建所有子项目
# 假设脚本在工程的父级目录
projectName="aa.xcodeproj"
projectPath=$(find . -name $projectName)
projectPath=${projectPath%/*}
cd $projectPath
 
projInfo=$(xcodebuild -list -project $projectName)
targetSchemes=${projInfo#*Schemes:}
 
for ((i=0; i<${#sortSchemeNames[@]}; i++)); do
    scheme=${sortSchemeNames[i]}
    if [[ $targetSchemes =~ $scheme ]]
    then
        echo "------------构建开始:${scheme}"
        xcodebuild \
        -destination ${plateformDevice} \
        -workspace ${param1}.xcworkspace \
        -scheme ${scheme} \
        -configuration 'Debug'
        echo "++++++++++++构建结束:${scheme} \n"
    fi
done
 

 

真机,模拟器分别归档,并打.xcframework包
# 真机,模拟器分别归档,并打.xcframework包
# 假设脚本在工程的当前目录
# 执行shell命令,查询当前目录下所有的*.xcodeproj文件
projPaths=$(find . -name *.xcodeproj)
projPath0=${projPaths[0]} # 获取第0个路径
projName=${projPath0##*/} # 获取xxx.xcproj工程名
onlyName=${projName%.*}   # 获取纯净的xxx工程名
 
 
xcodebuild archive \
    -scheme ${onlyName} \
    -sdk iphonesimulator \
    -archivePath "archives/ios_sim.xcarchive" \
    BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
    SKIP_INSTALL=NO
 
 
 
xcodebuild archive \
    -scheme ${onlyName} \
    -sdk iphoneos \
    -archivePath "archives/ios_device.xcarchive" \
    BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
    SKIP_INSTALL=NO
 
 
 
xcodebuild -create-xcframework \
    -framework archives/ios_device.xcarchive/Products/Library/Frameworks/${onlyName}.framework \
    -framework archives/ios_sim.xcarchive/Products/Library/Frameworks/${onlyName}.framework \
    -output build/${onlyName}.xcframework

 

批量查询与批量替换脚本例子
#!/bin/sh

filterList=("Pods" "libs" "Scripts" "Makefile" "Podfile" "Podfile.lock" "readme.md" "LEGAL.md" "Assets.xcassets" "xcshareddata" "xcuserdata" "build" "Images.xcassets" "Resources" "Products")
#filterFileList=(*.podspec)

# 如果没有输入cp参数,提示输入cp参数
paramNum=$#
subCmd=$1
param1=$2
param2=$3
readonly location=`pwd`
tempPath=""
subCmdValue1="s" #search
subCmdValue2="r" #replace

searchTotalCount=0



# ------------------search 查询-------------------


function checkFileAndDir() {
    searchPath=`pwd`

    # -iname:忽略大小写;-name:区分大小写;
    find ${searchPath} -iname $1
    
    echo "查询根目录:${searchPath}"
    items=`ls`
    #字符串转数组,将\n替换为空格
#    items=(${items//\n/ })
    echo $items
    index=0
    for item in `ls`; do
        index=`expr $index + 1`
        echo "\n++++++++开始查询第:${index}个项目,项目名称:${item}  ++++++++\n"
        searchOneDir $item
    done
}
        

function searchOneDir(){
    if [ -f ${1} ]; then
    
        if [[ ${1} == *\.podspec || ${1} == *\.pbxproj || ${1} == *\.plist || ${1} == *\.sh ]]; then
            return
        fi
        
#        echo "查询 ${1}"
        res=$(sed -n "/${param1}/Ip" ${1}) #I:取消大小写
#        res=$(sed -n "/${param1}/p" ${1})
        # 非空判断
        if [ -n "$res" ]; then
            searchTotalCount=`expr $searchTotalCount + 1`
            echo "\n递归目录------结果个数:${searchTotalCount} --------:$1 ;"
            echo $res
        fi
        
    elif [ -d ${1} ];then
        #sed -i "" "s/aaa/bbb/g" grep -rl aaa ./
        #grep -rl: l列出文件内容符合条件的文件名, r递归查询
        #$(grep -rl ${param1} ./ | xargs sed -n "/${param1}/Ip")
        
        if [[ ! "${filterList[@]}" =~ "${1}" ]]
        then
            items=$(ls $1)
    #        echo "递归目录------结果个数:${searchTotalCount}--------:$1 ;"
            for item in ${items[@]}; do
    #        for ((i=0; i<${#items[@]}; i++)); do
    #            item=${items[i]}

                # [[ $filterList =~ $item ]]字符串包含:父字符串$tragetSchemes 是否包含子字符串$scheme ?
                # [[ "${filterList[@]}" =~ "$item" ]]数组包含:数组$"{filterList[@]}" 是否包含字符串"$item" ?
                # [[ ! "${filterList[@]}" =~ "$item" ]]数组不包含?

                if [[ ! "${filterList[@]}" =~ "$item" ]]
                then
    #                echo "进入:$item"
                    searchOneDir "$1/$item"
                fi
             done
        fi
    fi
    return 0;
}


# ------------------replace 替换-------------------

function scannerOneDir(){
    echo "${1}"
    if [ -f ${1} ]
    then
#        if [[ ${1} == *\.podspec || ${1} == *\.sh ]]; then
#            return
#        fi
        
        echo "替换 ${1}"
        sed -i "" "s/${param1}/${param2}/g" ${1}
        echo "替换成功"
    elif [ -d ${1} ]
    then
        #sed -i "" "s/aaa/bbb/g" grep -rl aaa ./
        $(grep -rl ${param1} ./ | xargs sed -i "" "s/${param1}/${param2}/g")
    fi
    return 0;
}

function handle() {
    if [ $subCmd == $subCmdValue1 ]; then
       searchOneDir $1;
    else
       scannerOneDir $1;
    fi
}

function handleDir() {
    # 进入到目标目录里,进行替换
    if [[ ! "${filterList[@]}" =~ "$1" ]]
    then
        if [[ ${1} == *\.podspec || ${1} == *\.sh ]]; then
            echo "匹配失败:${1}"
        else
            echo "匹配成功:${1}"
            handle ${1};
        fi
    else
        echo "匹配失败:${1}"
    fi
}
 
function scanDir(){

    res=`find . -name *.xcodeproj`
    echo $res
    if [[ ! ${res} ]]
    then
        # 扫描的是一个普通文件夹
        for item in `ls`; do
            handleDir ${item};
        done
    else
        # 扫描的是一个xcode项目父文件夹
        for path in ${res[@]}; do
            pathT=${path%.*}
            tempPath=${pathT%/*}
            projName=${pathT##*/}
            if [ ${projName} != "Pods" ]
            then
                echo "------进入项目根目录:${tempPath}, 入参:${param1}, ${param2}"
                cd ${tempPath}
                echo "projName: ${projName}"
                for item in `ls`; do
                    handleDir ${item};
                done

                cd ${location}
                echo "++++++退回Ant目录:${location}\n"
            fi
        done
    fi
    return 0;
}



# <<的用法:
# 当shell看到<<的时候,它就会知道下一个词是一个分界符。
# 在该分界符以后的内容都被当作输入,直到shell又看到该分界符(位于单独的一行)。
# 这个分界符可以是你所定义的任何字符串。

# EOF与<<结合:
# 通常将EOF与<<结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell

# EOF特殊用法:
#EOF是(END Of File)的缩写,表示自定义终止符。既然自定义,那么EOF就不是固定的,可以随意设置别名,在linux按ctrl-d 就代表EOF。
#EOF一般会配合cat能够多行文本输出。
#其用法如下:
#<<EOF        #开始
#....         #输入内容
#EOF          #结束

#熟悉几个特殊符号:
#<:输入重定向
#>:输出重定向
#>>:输出重定向,进行追加,不会覆盖之前内容
#<<:标准输入来自命令行的一对分隔号的中间内容

# :<<COMMENTBLOCK
# shell脚本代码段
# COMMENTBLOCK
# 用来注释整段脚本代码。 :是shell中的空语句。


:<<EOF
shell 目录,文件判断
-f "file"   :  判断file是否是文件;
-d "file"  :  判断file是否是目录(文件夹)。
EOF

:<<EOF
xargs 将标准输入作为下一条命令的参数
$ echo "hello world" | xargs echo
hello world
上面的代码将管道左侧的标准输入,转为命令行参数hello world,传给第二个echo命令。
EOF


if [ $paramNum -lt 2 ]
then
   echo "请输入查询的字符串与要替换的新字符串"
else
    if [ $subCmd == $subCmdValue1 ]; then
        param1=$2
        param2=$3
        echo "开始查询:${param1}"
        checkFileAndDir ${param1}
    elif [ $subCmd == $subCmdValue2 ]; then
        param1=$2
        param2=$3
        echo "查询的字符串:${param1},要替换的新字符串:${param2}"
        scanDir
    else
        param1=$1
        param2=$2
        echo "查询的字符串:${param1},要替换的新字符串:${param2}"
        scanDir
    fi
    
fi

 

 

 

与Shell常用命令与脚本实例相似的内容:

Shell常用命令与脚本实例

#!/bin/sh echo "Hello shell" # 字符串 # readonly URL="定义一个常量:www.baidu.com" your_name="jack" echo $your_name echo ${your_name} for file in `ls ~/Desktop`

[转帖]Linux中最全shell命令&常用注意事项

在编辑linux脚本中不断的会用到复杂的脚本编辑,写文章记录。 Linux命令大全(手册) – 真正好用的Linux命令在线查询网站 目录 推荐书籍: Linux常用命令 Linux 常用命令 在linux shell脚本中root切换到普通用户执行脚本 Linux—shell中$(( ))、$(

[转帖]Shell三剑客之sed

目录 Shell三剑客sed工具sed 流编辑器的工作过程sed命令格式与选项操作符sed命令的常用选项sed命令的打印功能默认打印方式sed命令的寻址打印文本模式过滤行内容 sed的删除操作通过行号进行删除匹配字符串内容删除字符串搭配正则进行删除删除空行的三种方法 sed命令替换符进行大小写的替换

1.14 手工插入ShellCode反弹

PE格式是 Windows下最常用的可执行文件格式,理解PE文件格式不仅可以了解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,而有些技术必须建立在了解PE文件格式的基础上,如文件加密与解密,病毒分析,外挂技术等,本次的目标是手工修改或增加节区,并给特定可执行程序插入一段`ShellCode`代码,实现程序运行自动反弹一个Shell会话。

[转帖]Linux Shell sort排序常用命令

https://www.jianshu.com/p/75c69236963f 1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。 [rocrocket@rocrocket programming]$ ca

Hbase学习三:Hbase常用命令总结

转载请注明出处: 1.Hbase连接 1.1.进入hbase命令行 hbase shell # 或 bin/hbase shell 1.2.查看帮助 help 1.3.查看所有表 list 2.表操作 2.1.创建表 create 'user','basicinfo' 2.2.查看表结构 desc

[转帖]Django系列3-Django常用命令

文章目录 一. Django常用命令概述二. Django常用命令实例2.1 help命令2.2 version2.3 check2.4 startproject2.5 startapp2.6 runserver2.7 shell2.8 migrations2.8.1 makemigrations2

[转帖]ESXi命令行shell下最常用的命令

https://forum.huawei.com/enterprise/zh/thread/580931293695328256 services.sh – Linux服务通常使用services命令管理,管理ESXi服务是通过使用services.sh命令实现的。Services.sh命令支持的参

[转帖]Shell中常用的date时间命令

常用FORMAT %Y YYYY格式的年份(Year) %m mm格式的月份(),01-12 %d dd格式的日期(day of month),01-31 %H HH格式的小时数(),00-23 %M MM格式的分钟数(),00-59 %S SS格式的秒数(),00-59 %F YYYY-mm-dd

分享几个常用的运维 shell 脚本

今天咸鱼给大家分享几个不错的 Linux 运维脚本,这些脚本中大量使用了 Linux 的文本三剑客: 1. awk 2. grep 3. sed 建议大家这三个工具都要了解并最好能够较为熟练的使用 根据 PID 显示进程所有信息 根据用户输入的 PID,过滤出该 PID 所有的信息 #! /bin/