SHELL编程第一行的问题,请教!

sh/bash/dash/ksh/zsh等Shell脚本
回复
lixinneo
帖子: 8
注册时间: 2010-05-28 18:00

SHELL编程第一行的问题,请教!

#1

帖子 lixinneo » 2012-01-08 10:37

很多教程中都说shell编程第一行一定要是“#!/bin/bash”或者“#!/bin/sh”类似这样的一句告知系统的信息,我想问这个是必须的吗?我今天试了一下,不加这一句我的脚本一样可以运行,所以证明这一句不是必须的。但加和不加有什么区别呢?请知道的朋友帮助解释一下,谢谢!
lwbskfish
帖子: 323
注册时间: 2007-02-05 18:09

Re: SHELL编程第一行的问题,请教!

#2

帖子 lwbskfish » 2012-01-08 11:23

不写的时候系统用的是默认的命令解释器,是/bin/sh或者/bin/bash(不太清楚是哪个),所以可以运行。/bin/sh一般链接到/bin/bash,但是bash如果检测到自己是从/bin/sh启动的,会尽量模拟旧式的sh。两者有少数代码不兼容,并且bash略慢。
lixinneo
帖子: 8
注册时间: 2010-05-28 18:00

Re: SHELL编程第一行的问题,请教!

#3

帖子 lixinneo » 2012-01-08 12:21

lwbskfish 写了:不写的时候系统用的是默认的命令解释器,是/bin/sh或者/bin/bash(不太清楚是哪个),所以可以运行。/bin/sh一般链接到/bin/bash,但是bash如果检测到自己是从/bin/sh启动的,会尽量模拟旧式的sh。两者有少数代码不兼容,并且bash略慢。
那我可以这样理解吗:
"#!/bin/bash"只是一个帮助性的语句,对脚本的运行没有实质的影响,写了最好,不写也无所谓,不是必须的。
头像
ljj_jjl2008
论坛版主
帖子: 14256
注册时间: 2007-09-16 8:29

Re: SHELL编程第一行的问题,请教!

#4

帖子 ljj_jjl2008 » 2012-01-08 12:26

lixinneo 写了:
lwbskfish 写了:不写的时候系统用的是默认的命令解释器,是/bin/sh或者/bin/bash(不太清楚是哪个),所以可以运行。/bin/sh一般链接到/bin/bash,但是bash如果检测到自己是从/bin/sh启动的,会尽量模拟旧式的sh。两者有少数代码不兼容,并且bash略慢。
那我可以这样理解吗:
"#!/bin/bash"只是一个帮助性的语句,对脚本的运行没有实质的影响,写了最好,不写也无所谓,不是必须的。
有区别。
我认为是必须的。
我这里,如果不写这一句,带case语句的shell运行不正常,写上才正常。
lixinneo
帖子: 8
注册时间: 2010-05-28 18:00

Re: SHELL编程第一行的问题,请教!

#5

帖子 lixinneo » 2012-01-08 12:50

ljj_jjl2008 写了:
lixinneo 写了:
lwbskfish 写了:不写的时候系统用的是默认的命令解释器,是/bin/sh或者/bin/bash(不太清楚是哪个),所以可以运行。/bin/sh一般链接到/bin/bash,但是bash如果检测到自己是从/bin/sh启动的,会尽量模拟旧式的sh。两者有少数代码不兼容,并且bash略慢。
那我可以这样理解吗:
"#!/bin/bash"只是一个帮助性的语句,对脚本的运行没有实质的影响,写了最好,不写也无所谓,不是必须的。
有区别。
我认为是必须的。
我这里,如果不写这一句,带case语句的shell运行不正常,写上才正常。
我自己试了一下带case的语句,是可以正常运行的,没有问题。用的就是《鸟哥私房菜》的例子sh11.sh,环境是ubuntu10.04。我至今都没有发现加第一句和不加第一句的区别。ljj_jjl2008如果不介意的话能把你的脚本发给我吗?我试试看。谢谢!我的邮箱: [email protected]
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: SHELL编程第一行的问题,请教!

#6

帖子 tusooa » 2012-01-08 13:16

lixinneo 写了:
ljj_jjl2008 写了:
lixinneo 写了:
lwbskfish 写了:不写的时候系统用的是默认的命令解释器,是/bin/sh或者/bin/bash(不太清楚是哪个),所以可以运行。/bin/sh一般链接到/bin/bash,但是bash如果检测到自己是从/bin/sh启动的,会尽量模拟旧式的sh。两者有少数代码不兼容,并且bash略慢。
那我可以这样理解吗:
"#!/bin/bash"只是一个帮助性的语句,对脚本的运行没有实质的影响,写了最好,不写也无所谓,不是必须的。
有区别。
我认为是必须的。
我这里,如果不写这一句,带case语句的shell运行不正常,写上才正常。
我自己试了一下带case的语句,是可以正常运行的,没有问题。用的就是《鸟哥私房菜》的例子sh11.sh,环境是ubuntu10.04。我至今都没有发现加第一句和不加第一句的区别。ljj_jjl2008如果不介意的话能把你的脚本发给我吗?我试试看。谢谢!我的邮箱: [email protected]
不加就是默认/bin/sh.
估计你那里/bin/sh链接到了bash.

代码: 全选

] ls -ld //
头像
sunfish
帖子: 989
注册时间: 2008-05-03 1:53

Re: SHELL编程第一行的问题,请教!

#7

帖子 sunfish » 2012-01-08 13:23

这个是有用的,这句就是提示当前shell用什么解释器来执行下面的脚本命令,比如你这句用:
#!/bin/cat就是用cat来执行,那就是把下面的内容显示了一把,其他如perl命令解释器等等类似,
主要是可以利用任何命令来做解释器
如果你没有这一行,shell默认是你在终端输入的命令,直接当前shell执行了
docker && kubernetes
lixinneo
帖子: 8
注册时间: 2010-05-28 18:00

Re: SHELL编程第一行的问题,请教!

#8

帖子 lixinneo » 2012-01-08 13:47

sunfish 写了:这个是有用的,这句就是提示当前shell用什么解释器来执行下面的脚本命令,比如你这句用:
#!/bin/cat就是用cat来执行,那就是把下面的内容显示了一把,其他如perl命令解释器等等类似,
主要是可以利用任何命令来做解释器
如果你没有这一行,shell默认是你在终端输入的命令,直接当前shell执行了
嗯,谢谢,sunfish应该是说到点子上了。那我就想问问用解释器来执行脚本命令直接用当前shell执行,这两者有区别吗?我感觉运行的结果都是一样的啊。
还有一点,我发现在ubuntu下你在脚本上加了"#!/bin/bash"并不意味着这个脚本一定用bash来执行,譬如你的脚本是scr.sh, 你在终端输入sh scr.sh时, 它是用dash来执行的,并没有因为你加了"#!/bin/bash"它就用bash,不信可以试试,在加了就在脚本里"#!/bin/bash"后写一句: echo -e "Hello World!", 保存为scr.sh,当你终端输入sh scr.sh运行后,屏幕上输出的是"-e Hello World!"。
头像
link_01
帖子: 1024
注册时间: 2008-11-05 13:24

Re: SHELL编程第一行的问题,请教!

#9

帖子 link_01 » 2012-01-08 13:56

sh scr.sh你就是显式使用dash等解析器,而多数脚本本身就不是这么用;
比方说你当前shell是dash,以bash的方式写的脚本有了#!/bin/bash只要系统安装有bash直接执行就是,为什么要强制用不兼容的方式?
笔记
-------------------------------------
http://blog.163.com/wqt_1101
头像
josephyoung
帖子: 158
注册时间: 2011-11-05 18:53
来自: 南极圈

Re: SHELL编程第一行的问题,请教!

#10

帖子 josephyoung » 2012-01-08 18:00

lixinneo 写了:
sunfish 写了:这个是有用的,这句就是提示当前shell用什么解释器来执行下面的脚本命令,比如你这句用:
#!/bin/cat就是用cat来执行,那就是把下面的内容显示了一把,其他如perl命令解释器等等类似,
主要是可以利用任何命令来做解释器
如果你没有这一行,shell默认是你在终端输入的命令,直接当前shell执行了
嗯,谢谢,sunfish应该是说到点子上了。那我就想问问用解释器来执行脚本命令直接用当前shell执行,这两者有区别吗?我感觉运行的结果都是一样的啊。
还有一点,我发现在ubuntu下你在脚本上加了"#!/bin/bash"并不意味着这个脚本一定用bash来执行,譬如你的脚本是scr.sh, 你在终端输入sh scr.sh时, 它是用dash来执行的,并没有因为你加了"#!/bin/bash"它就用bash,不信可以试试,在加了就在脚本里"#!/bin/bash"后写一句: echo -e "Hello World!", 保存为scr.sh,当你终端输入sh scr.sh运行后,屏幕上输出的是"-e Hello World!"。
当你用sh来执行的时候,意思是让系统用/bin/sh来执行你的脚本,这种执行方法跟#!/bin/sh没有关系,这样执行加不加都可以。
但当把脚本设置为可执行,并用绝对路径或相对路径来直接执行的时候,就需要有#!/bin/sh了,这句话虽然开头有#号,但并不是注释,因为#后面还有个!,#!是个整体,表示这个脚本需要调用哪个命令解释器。因为能写成脚本的多了,可不只是bash。包括/bin/sed,/usr/bin/awk,/usr/bin/perl,/usr/bin/python等等等等,如果没有那句话,系统只会默认调用/bin/sh(说的是用./scr.sh这种执行方式,你也可以在运行的时候用sed -f scr.sh等等各个命令自己语法来调用)
xiii_1991
帖子: 47
注册时间: 2008-12-27 15:16

Re: SHELL编程第一行的问题,请教!

#11

帖子 xiii_1991 » 2012-01-08 23:19

这是一个脚本必须的,不只是shell脚本,如果是shell,就这样写,别的脚本有别的写法。
好像csh和bash的脚本就不一样,就需要注明。

如果你写的是python的或者perl的脚本呢?开头也要写明白是python脚本或是perl脚本。
因为就linux系统看来,他们都是文本文件而已。
tivooooli
帖子: 88
注册时间: 2008-06-04 12:50
来自: Beckosecurity
联系:

Re: SHELL编程第一行的问题,请教!

#12

帖子 tivooooli » 2012-01-09 9:04

它的意思就是调用哪一个解释器来执行脚本,比如说python脚本,就是这样的:

代码: 全选

#!/usr/bin/env python
加与不加的区别:
加了的话(文件名:hello.py),可以直接执行

代码: 全选

./hello.py
不加的话会这样

代码: 全选

python hello.py
www.beckosecurity.com
----
TivooooLi
头像
poweroff
帖子: 395
注册时间: 2008-12-13 15:03

Re: SHELL编程第一行的问题,请教!

#13

帖子 poweroff » 2012-01-09 11:23

你如果写个csh脚本不写开头,直接运行,必然出错
一条狗的马甲!
对不起,我承认我是一只穿着马甲的狗!
lixinneo
帖子: 8
注册时间: 2010-05-28 18:00

总结: SHELL编程第一行的问题,请教!

#14

帖子 lixinneo » 2012-01-09 12:53

感觉论坛里各位朋友的指教,这个问题我基本上搞明白了,下面我来总结一下,如果有不对的地方希望朋友们指正。

1. SHELL里的第一句(类似"#!/bin/bash")是需要的,但不是必须的。不是必须的意思是:你不加,系统一样会用其默认的脚本执行或者用命令强制执行,该脚本是可以运行的。举个例子:你当前在dash下想用bash去执行个名为src.sh的脚本,如果你在脚本第一行加了"#!/bin/bash",在执行时你输入

代码: 全选

./src.sh
,系统就会用bash去执行该脚本,不论你目前使用的是什么shell。如果你在脚本第一行没有加"#!/bin/bash",在执行时你输入

代码: 全选

./src.sh
,系统就会用默认的dash去执行该脚本;或者你可以用命令强制执行,

代码: 全选

bash ./src.sh
,这样也是用bash去执行脚本。所以加不加是可以根据个人需要定的。

2. 另一种情况, 当你的脚本加了第一句"#!/bin/bash",在执行时使用强制执行,

代码: 全选

dash ./src.sh
,那么系统会忽略第一句,用dash去执行你的脚本。

3. 在Ubuntu10.04中, sh默认是指向dash,即你输入sh scr.sh,系统是用dash来执行scr.sh。(其他版本没试过)

根据朋友们指教和自己的实验,我总结出了以上三条,希望能对大家尤其是初学者有帮助。
头像
TeliuTe
论坛版主
帖子: 7675
注册时间: 2007-11-25 13:29
系统: 16/18/20/w7
来自: 新疆博乐
联系:

Re: SHELL编程第一行的问题,请教!

#15

帖子 TeliuTe » 2012-01-09 13:11

学习了
回复