linux shell [: missing ],shell 脚本学习答疑

继上篇 shell 入门文章, 该篇文章会列举出我在学习 shell 的过程中, 遇到的一些疑问, 然后自己查资料以后的解答.

如何运行 shell 脚本

回顾例子:

[root@host shell]# vim start

[root@host shell]# cat start

#!/bin/bash

echo 'hello'

[root@host shell]# chmod 755 start

[root@host shell]# ./start

hello

[root@host shell]#

执行时, 为什么要加 ./ ?

这要从系统的 $PATH 变量说起, 当我们执行例如 ls, pwd 等指令时, linux 并不会在整个系统翻箱倒柜搜索 ls, pwd 程序, 而是会从 $PATH 变量定义的目录列表下查找, 如果找不到, 就会报 command not found 的错误.

因为我们的脚本不在 $PATH 变量目录列表下, 所以需要加上 ./ 指示该应用程序处于当前目录下.

另外, 如果我们不想加 ./, 可以将该目录作为系统搜寻指令的其中一个目录:

[root@host shell]# vim ~/.bash_profile

# 修改 .bash_profile, 添加你的脚本目录.

# $PATH 变量定义中, 多个目录用冒号 : 分隔

export PATH="$PATH":~/shell

# 让 shell 重新读取配置文件

[root@host shell]# source ~/.bash_profile

[root@host shell]# start

hello

第一行 #!/bin/bash 有什么作用 ?

告诉操作系统用什么解释器执行该脚本

为什么要给文件加权限 chmod 755 ?

linux 系统默认不允许一个文本文件作为程序被执行, 所以要给文件添加可执行的权限

shell 和 bash 有什么关系 ?

shell 是一类应用程序, 它接收键盘输入的命令, 然后将命令传递给操作系统去执行, 是用户与操作系统的沟通桥梁.

bash 是使用广泛的一款 shell 程序, Linux 系统的标配, 也可以使用其他 shell 程序, 比如 sh.

~/.bashrc, ~/.bash_profile 文件有什么区别 ?

这两个文件都是 shell 脚本文件, 会在不同的时机被执行.

~/.bash_profile 会在 linux 用户登录的时候被执行.

~/.bashrc 在非登录时就会被执行.

另外, 一般在 ~/.bash_profile 脚本内, 会将 ~/.bashrc 内容进行执行, 比如某些服务器的 ~/.bash_profile 文件内, 会有代码:

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

shell 命令内自带程序名字的来源有哪些 ?

在 shell 的配置文件中, 比如 ~/.bashrc, 内定义的 $PATH 目录列表中可找到的程序

在 shell 配置文件内定义的 shell 函数

数据类型

回顾数组

# 初始化

a[2]=100

a=(2 4 'str' 4)

a=([0]=2 [2]='str' [4]=20)

# 单个赋值

a[2]='s'

# 打印整个数组

echo ${a[@]}

# 遍历数组

for i in ${a[@]}; do

echo $i

done

# 数组元素个数

echo ${#a[@]}

# 指定下标添加元素

a=([0]=2 [2]='str')

a[3]=1

a[6]=6

# 删除整个数组

unset a

# 删除数组内单个元素

unset a[1]

数组内可以放置字符串和整数的混搭吗 ?

可以, 比如

a=( [1]=sun [6]=$((2+3)) )

对数组进行跨越 (不连续) 赋值, 遍历数组时, 会遍历未赋值元素吗 ?

不会

a=( [1]=sun [6]=$((2+3)) )

for i in ${a[*]}; do

echo 0

echo $i

done

# 0

# sun

# 0

# 5

' 和 " 区别 ?

[root@host shell]# echo "$foo"

start

[root@host shell]# echo '$foo'

$foo

双引号内, 会进行参数展开.

单引号内, 不进行参数展开.

什么是参数展开 ?

即 将变量名替换为具体的值, 比如

[root@host shell]# a="-l"

[root@host shell]# ls $a

total 4

-rwxr-xr-x 1 root root 26 Oct 19 07:29 start

ls $a 参数展开以后会是 ls -l

变量, 表达式, 控制流

为什么要给变量加花括号 {} ?

a=1

echo ${a} # 1

echo $a # 1

以上, a 变量加不加花括号都没关系, 但是一些情况下, 需要给变量加上花括号, 为了更清晰的指出我们操作的是什么变量

例如我想修改文件名, 给文件名末尾加一个 "1"

[root@host shell]# foo=start

[root@host shell]# mv $foo $foo1

mv: missing destination file operand after ‘start’

Try 'mv --help' for more information.

[root@host shell]# mv $foo ${foo}1

[root@host shell]# ll

total 4

-rwxr-xr-x 1 root root 26 Oct 19 07:29 start1

有哪些 $ 开头的 shell 自带变量 (待完善) ?

$? # 上一次的退出状态

$REPLY # 当使用 read 命令, 且 read 没带变量名, 则 $REPLY 包含所有输入

$(( )) 与 (( )) 区别 ?

复合命令 (( )), 用做算术运算, 用在条件判断中, 比如 if 的条件判断.

而 $(( )) 用作算术展开, 用作整数赋值, 比如 foo=$((1))

( ) 与 (( )) 区别 ?

( ) 用于创建 子shell, 应该与 { } 一起讲

(( )) 用于算术表达式求值, 可用在条件判断中

( ) 与 { } 区别 ?

二者语法为

( list ) # 子 shell

# eg

( ls -l; echo 'hello' ) > output.txt

{ list; } # 组合命令

# eg

{ ls -l; echo 'hello'; } > output2.txt

二者都可以内置一个命令列表, 运行以后会执行该命令列表.

语法上的不同:

在组合命令中, { 与 list 之间需要一个空格, 而 { list; } 的 list 最后需要带上分号 ;, 而 ( list ) 没有这些限制

功能上的不同:

组合命令会在当前环境执行该命令列表, 产生的对环境变量的变动会保留在当前执行环境.

而子 shell 则会新建一个执行环境, 在新的执行环境内执行命令列表, 所以当子 shell 内命令列表执行完以后, 子 shell 会被销毁, 子 shell 内的环境变量也会相应的被销毁.

[ ] 与 [[ ]] 区别 ?

[ ] 用于控制流中的条件判断.

[[ ]] 拥有 [ ] 的能力, 且增加了正则表达式的能力.

$(( )) 与 (( )) 结合使用 ?

a=0

if (( $(( $a + 1 )) == 1 )); then

echo 'hello'

fi

解析:

if 跟着的 (( )) 是复合命令, 用作条件判断

内部的 $(( $a + 1 )) 是算术展开, 用作算术求值

$a + 1 是一个表达式

其他

如何在 vim 编辑器里运行 linux 命令 ?

Esc

:!linux_command

注意: 如果要运行正在编辑的 shell 脚本, 记得先进行保存: :w

参考

(如有错误或不同的见解, 望不吝指出, 愿共同进步!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值