Linux shell程序无法正常执行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux shell程序无法正常执行相关的知识,希望对你有一定的参考价值。

#!/bin/bash

#

FLIE=/evvvvvtc/rc.d/rc.sysinit

#

if [ ! -e $FILE ]; then

echo "No such file $FILE"

exit 8

fi

if [ -f $FILE ]; then

echo "this file is normal"

elif [ -d $FILE ];then

echo "this is a dictionary file"

else

echo "Yes"

fi

执行结果:this file is normal

(实际应该是:"No such file =/evvvvvtc/rc.d/rc.sysinit

)

注:bash -x file.sh执行结果

+ FLIE=/evvvvvtc/rc.d/rc.sysinit

+ '[' '!' -e ']'

+ '[' -f ']'

+ echo 'this file is normal'

this file is normal

判断时应该给FILE变量加上引号:
if [ ! -e "$FILE" ]; then
参考技术A 你拼错了吧
变量是FLIE
但是后面调用是FILE

Shell笔记

shell基础

1、shell在Windows和Linux中都有命令转换器的作用,另外它还是一门编程语言

2、shell编程第一行都有加上#!/bin/bash,它的作用是告诉系统这是一个shell程序

3、Windows中的shell程序在Linux中无法正常执行,这是因为二者的回车符不一样,可以使用dos2unix来对程序进行转换

4、history语句  查看此次登录的命令的历史记录

-c  清除所有的历史记录,包括~/.bash_history文件内的

-w  将此次登录的历史记录保存进 ~/.bash_history文件

上下键调用以前的历史命令

!n  调用第n条历史命令

!!  执行上一条历史命令

!字符串  执行上一条以该字符串开头的命令

5、alias  给命令起别名

alias vi=‘vim‘

以上只是临时生效,一旦退出将失效

要想将别名永久生效,就需要改变~/.bashrc文件,将起别名的命令写入此文件,别名将永久生效

unalias  删除别名

6、Bash常用快捷键

ctrl+U  删除或剪切光标之前的命令

ctrl+K  删除或剪切光标之后的命令

ctrl+Y  粘贴ctrl+U或ctrl+K剪切的命令

ctrl+R  在历史命令中搜索

ctrl+D  退出当前终端

7、输入、输出重定向

(1)输入重定向:

命令&>文件  命令&>>文件

&的作用是不论命令正确或是错误,都把输出保存到文件中

>的作用是以覆盖的方式保存到文件  >>的作用是以追加的方式保存到文件

命令>>文件1 2>>文件2  将正确输出和错误输出分别追加保存到两个文件中(以覆盖保存的方式也可以,但是当保存一个文件时,另一个文件会被清空)

(2)输出重定向:(使用频率很低)

命令 < 文件

例:wc命令  统计行数、单词数、字符数

wc < 文件

wc << 字符  以字符为结尾统计

8、多命令执行和管道符

多命令执行:

(1)常见的多命令执行符

命令1;命令2···  单纯的连接多个命令

命令1&&命令2···  当命令1正确执行时才执行命令2

命令1||命令2···  当命令1不正确执行时才执行命令2

(2)命令 && echo yes || echo no

判断命令是否正确执行  

管道符:

(1)命令1 | 命令2

命令1的正确输出作为命令2的操作对象

9、通配符和其他特殊符号

(1)通配符

?代表一个字符    *代表任意字符(包含空字符)

[]代表指定范围内的一个字符

例:[0-9]代表0到9内的一个数字

[^0-9]代表非数字的一个字符

(2)Bash中其他特殊符号

‘‘单引号      在单引号中的符号都只是符号,没有任何特殊含义

""双引号      在双引号中特殊字符都没有特殊含义,但是"$"、"`"和"\"是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义

$()          用来引用系统命令

例:echo $(date)     将date命令执行的结果赋值给echo

Bash变量:用户自定义变量》环境变量》位置参数变量》预定义变量

用户自定义变量对用户没有任何限制

环境变量中的系统环境变量,用户不能改变变量名,只能改变变量值。除此之外,用户可以自己自定义环境变量。

位置参数变量属于预定义变量中的一类,都是不能改变变量名,只能改变变量值。

10、Bash变量——用户自定义变量

(1)Bash中,变量的默认类型是字符串型,如果要进行数值运算,则必须指定变量类型为整形

(2)等号两边不能有空格,如果值中有空格,则需要用单引号或双引号括起来

(3)变量的值可以叠加,叠加规则如下:

例:aa=123

       aa="$aa"456

       aa=${aa}789

(4)环境变量名建议大写,便于区分

(5)set查看系统中所有变量

(6)unset     删除变量

11、Bash变量——环境变量

(1)export 变量名=变量值          申明环境变量

         env                                       查询环境变量

         unset                                                    删除变量

(2)系统常见的环境变量

PATH:系统查找命令的路径

在Linux中如果要执行一个程序(命令也是一个程序),必须使用绝对路径或是相对路径,但是我们平时使用的命令的开头并没有路径,原因就在于系统会自动在环境变量PATH中所包含的路径内寻找。如果我们想要使自己编写的程序也可以直接通过文件名来执行,只需要将我们的文件移动到PATH中默认的路径中(但这种方式不太推荐),或者修改环境变量PATH,例如PATH="$PATH":/home/pi/

PS1:定义系统提示符的变量

自定义变量和环境变量区别:用户自定义变量只在当前的shell中生效,而环境变量会在当前shell和这个shell所有子shell中生效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的shell中生效。

12、Bash变量——位置参数变量

         $n      $0代表命令本身,$n代表第n个参数,当n大于9时,形式变为${n}

         $*       这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体

         [email protected]     这个变量也代表命令行中所有的参数,[email protected]把每个参数区分对待

         $#       这个变量代表命令行中所有参数的个数

13、Bash变量——预定义变量

(1)$?       最后一次执行的命令的返回状态。如果这个变量为0,就证明上一条命令正确执行。如果这个变量非0(具体数值有程序自己来决定),则证明上一条命令执行错误。

         $$       当前进程的进程号(PID)

         $!        后台运行的最后一个程序的进程号(PID)

(2)接受键盘输入

read [选项] [变量名]

选项:-p "提示信息"          在等待read输入时,输出提示信息

           -t 秒数                     指定等待时间

           -n 字符数                read命令只接受指定的字符数,就会执行,不需要再按回车

           -s                            隐藏输入的数据,用于机密信息的输入

14、Bash的运算符——数值运算与运算符

在shell中进行数值运算

方法一:

declare        声明变量类型

declare [+/-] [选项] 变量名

选项:-           给变量设定类型属性

           +          取消变量的类型属性

           -i          将变量声明为整形

           -x         将变量声明为环境变量

           -p         显示指定变量的被声明的类型

例:declare -i cc=$aa+$bb

方法二:

$((运算式))或$[运算式]

例:cc=$(($aa+$bb))

15、环境变量配置文件

(1)source命令

source 配置文件 或 . 配置文件             令配置文件立即生效(注意:.和配置文件中间有空格)

 

shell编程

1、正则表达式

(1)正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。

         通配符用来匹配符合条件的文件名,通配符是完全匹配。因为ls、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配。

(2)基础正则表达式

        *         前一个字符匹配0次或任意多次

        .         匹配除换行符外任意一个字符

        ^        匹配行首。例如:^hello会匹配以hello开头的行

        $        匹配行尾。例如:hello$会匹配以hello结尾的行

        []        匹配中括号中指定的一个字符

        [^]      匹配除中括号内字符以外的任意一个字符

        \          转义符。用于取消特殊符号的含义

       \{n\}     表示其前面的字符恰好出现n次

       \{n,\}    表示其前面的字符至少出现n次

       \{n,m\}     表示其前面的字符至少出现n次,至多出现m次

例:grep -n "^$" test.txt           匹配空白行(-n的作用是显示行号)

       grep "^[^a-zA-Z]" test.txt       匹配不要字母开头的行

grep处理的是行,而cut,awk处理的都是列

2、字符截取命令——cut命令

cut [选项] 文件名

选项:

          -f 列号                    提取第几列

          -d 分隔符               安装指定分隔符分割列

cut主要和grep配合使用,来提取特定的数据

cut只能用来提取用制表符,逗号,冒号,句号等符号作为分隔的文件,不能提取用空格来分隔的文件。

3、字符截取命令——awk命令

(1)awk ‘条件1{动作1} 条件2{动作2}···‘ 文件名

条件:一般使用关系表达式作为条件

           x>10    x>=10    x<10

动作:格式化输出

           流程控制语句

注意:在awk中,print后面自带换行,printf则需要手动添加

例:awk ‘{printf $1 "\t" $2 "\n"}‘ test.txt

       awk ‘BEGIN{FS=":"} {print $1 "\t" $3} END{print "The End!"}‘ test.txt

awk的默认分隔符是空格和制表符,使用FS可以指定分隔符

       cat text.txt | grep -v Name | awk ‘$6>86{print $2}‘          (grep -v Name 输出不含Name的行)

4、字符截取命令——sed命令

(1)sed是一种几乎包括在所有UNIX平台(包括Linux)的轻量级流编辑器。sed是主要用来将数据进行选取、替换、删除、新增的命令。

(2)sed [选项] ‘[动作]‘ 文件名

选项:-n             一般sed命令会把所有数据都输出到屏幕上,如果加上此选项,则只会把经过sed命令处理的行输出到屏幕上

           -e             允许对输入数据应用多条sed命令编辑

           -i              用sed的修改结果直接修改源文件,而不是由屏幕输出

动作:a              追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用\代表数据未完结

           c              行替换,用c后面的字符串替代原数据行。替换多行时,除最后一行外,每行末尾需要用\代表数据未完结

           i               插入,在当前行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用\代表数据未完结

           d              删除,删除指定的行

           p              打印,输出指定的行

           s              字符串替换,用一个字符串替换另一个字符串。格式为"行范围s/旧字符串/新字符串/g"

例:sed -n ‘2p‘ test.txt           打印第二行

       sed ‘2,4d‘ test.txt                         删除第二行到第四行

       sed ‘2a hello‘ test.txt                   在第二行后追加hello

       sed ‘2i hello\world‘ test.txt         在第二行前插入两行数据(如果追加两行数据,\后面需要按回车)

       sed ‘1,4c hello\world‘ test.txt     数据替换

       sed -e ‘1s/one/two/g;3s/three/four/g‘ test.txt      把第一行的one替换为two,同时把第二行的three替换为four(注意:必须是字符串,不能是字符串里的几个字符)

       sed -i ‘3s/one/two/g‘ test.txt       sed的操作直接写入源文件

5、字符处理命令

(1)排序命令sort

sort [选项] 文件名

选项:-f                  忽略大小写

           -n                 以数值型进行排序,默认使用字符串型排序

           -r                  反向排序

           -t                  指定分隔符,默认分隔符是制表符

           -k n[,m]        按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾)

例:sort test.txt

       sort -n -t ":" -k 3,3 test.txt           以:为分隔符的第三个字段按数值型排序

一般选项都不加

(2)统计命令wc

wc [选项] 文件名

选项:-l         只统计行数

           -w       只统计单词数

           -m       只统计字符数

6、条件判断

(1)按照文件类型进行判断

-d      判断该文件是否存在,并且是否为目录文件

-e      判断该文件是否存在

-f       判断该文件是否存在,并且是否为普通文件

-L      判断该文件是否存在,并且是否为符号链接文件

两种判断格式:test -e test.txt

                         [ -e test.txt ]         前后必须都空格

例:[ -f ~/test.txt ] && echo yes || echo no

(2)按照文件权限进行判断

-r       判断文件是否存在,并且该文件是否拥有读权限

-w      判断文件是否存在,并且该文件是否拥有写权限

-x       判断文件是否存在,并且该文件是否拥有执行权限

(3)两个文件之间进行比较

文件1 -nt 文件2        判断文件1的修改时间是否比文件2早

文件1 -ot 文件2        判断文件1的修改时间是否比文件2晚

文件1 -ef 文件2        判断文件1和文件2的lnode号是否一致,可以理解为两个文件是否为同一个文件

(4)两个整数之间比较

整数1 -eq 整数2        判断整数1是否和整数2相等

整数1 -ne 整数2        判断整数1是否和整数2不相等

整数1 -gt 整数2         判断整数1是否大于整数2

整数1 -lt 整数2          判断整数1是否小于整数2

整数1 -ge 整数2        判断整数1是否大于等于整数2

整数1 -le 整数2         判断整数1是否小于等于整数2

例:[ 33 -gt 55 ] && echo yes || echo no

(5)字符串的判断

-z 字符串              判断字符串是否为空

-n 字符串             判断字符串是否存在

字符串1 == 字符串2         判断字符串1是否和字符串2相等

字符串1 != 字符串2        判断字符串1是否和字符串2不相等

例:[ -z "$name" ] && echo yes || echo no

       [ $aa == $bb ] && echo yes || echo no

(6)多重条件判断

判断1 -a 判断2            逻辑与,判断1和判断2都成立,最终结果才为真

判断1 -o 判断2            逻辑或,判断1和判断2有一个成立,最终结果就为真

! 判断                          逻辑非,使判断式取反

例:[ -n $aa -a $aa -gt 23 ] && echo yes || echo no

7、流程控制——if语句

(1)单分支if条件语句

if [ 条件判断式 ];then

    程序

fi

或者

if [ 条件判断式 ]

    then

        程序

fi

例:rate=$(df -h | grep "/dev/root" | awk ‘{print $5}‘ | cut -d "%" -f 1)

       if [ $rate -ge 80 ]

               then

                        echo "/dev/root is full."

       fi

(2)双分支if条件语句

if [ 条件判断式 ]

          then

                     条件成立时,执行的程序

          else

                     条件不成了时,执行的程序

fi

(3)多分支if条件语句

if [ 条件判断式1 ]

            then

                             当条件判断式1成立时,执行程序1

elif [ 条件判断式2 ]

            then

                              当条件判断式2成立时,执行程序2

···省略更多条件···

else

            当所有条件都不成立时,最后执行此程序

fi

注意:shell中的多分支if条件语句当一个条件判断式为真并且执行了相应的程序后并不会退出,而是继续执行,因此最后在每个执行程序后面都加上exit(()

8、流程控制——case语句

case $变量名 in

       "值1")

                     如果变量的值等于值1,则执行程序1

                    ;;

        "值2")

                     如果变量的值等于值2,则执行程序2

                     ;;

···省略其他分支···

         *)

                     如果变量的值不是以上的值,则执行此程序

                     ;;

easc

例:

read -p "Please input your name: " -t 20 name

read -p "Please choose your sex(M/W):  " -t 15 sex

case     $sex in

        M)

                       echo "Hello, Mr $name"

         ;;

        W)

                        echo "Hello, Mrs $name"

          ;;

         *)

                         echo "Your sex is error!"

           ;;

easc

9、流程控制——for循环

(1)语法一

for 变量 in 值1 值2 值3···

         do

                     程序

         done

例:打印~/sh目录下的以.sh结尾的文件名

#!/bin/bash

cd ~/sh

ls *.sh > ls.log

num=1

for i in $(cat ls.log)

        do

                echo "$num  $i"

                num=$(($num+1))

        done

 

rm -rf ls.log

(2)语法二
for ((初始值;循环控制条件;变量变化))
         do
                      程序
         done
例:
#!/bin/bash
s=0
for ((i=1;i<=100;i=i+1))
        do
                s=$(($s+$i))
        done
echo "The sum 1+2+3···+99+100 is:$s"
10、流程控制——while循环与until循环
(1)while循环
while [ 条件判断式 ]
       do
                 程序
       done
例:
#!/bin/bash
sum=0
i=1
echo "This is a program that from 1 add to num"
read -p "Please input the num: " -t 30 num
while [ $i -le $num ]
        do
                sum=$(($sum + $i))
                i=$(($i + 1))
        done
echo "from 1 add to $num, the sum=$sum"
(2)until循环
until循环和while循环相反,until循环时只要条件判断式不成立则进行循环。一旦循环条件成立,则终止循环。
until [ 条件判断式 ]
         do
                    程序
         done
例:
#!/bin/bash
sum=0
i=1
echo "This is a program that from 1 add to num"
read -p "Please input the num: " -t 30 num
until [ $i -gt $num ]
        do
                sum=$(($sum + $i))
                i=$(($i + 1))
        done
echo "from 1 add to $num, the sum=$sum"

 



以上是关于Linux shell程序无法正常执行的主要内容,如果未能解决你的问题,请参考以下文章

linux 开机自启动 无法启动java相关程序

Shell笔记

linux脚本中执行命令

命令在控制台中能正常执行但在shell脚本中却无法执行?

无法从Electron打包应用程序执行shell命令

Python中的Linux Bruteforce。脚本工作正常,但我没有得到shell