首页 | 论坛 | Linux | 博客 | 下载 | 人才 | 培训 | WIKI | 手册 | 图书 | 搜索  
ChinaUnix.net » Shell » shell 十三問?

2003-12-9 02:48 網中人
shell 十三問?

我在 CU 的日子並不長,有幸在 shell 版上與大家結緣。
除了跟眾前輩學習到不少技巧之外,也常看到不少朋友的問題。
然而,在眾多問題中,我發現許多瓶頸都源於 shell 的基礎而已。
每次要解說,卻總有千言萬語不知從何起之感...

這次,我不是來回答,而是準備了關於 shell 基礎的十三個問題要問大家﹗
希望 shell 學習者們能夠透過尋找答案的過程,好好的將 shell 基礎打紮實一點...
當然了,這些問題我也會逐一解說一遍。只是,我不敢保證甚麼時候能夠完成這趟任務。
除了時間關係外,個人功力實在有限,很怕匆忙間誤導觀眾就糟糕了。
若能拋磚引玉,誘得其他前輩出馬補充,那才真的是功德一件﹗

shell 十三問:

1) 為何叫做 shell ?
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=2#pid1454336[/url]
2) shell prompt(PS1) 與 Carriage Return(CR) 的關係? (2008-10-30 02:05 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=2#pid1467910[/url]
3) 別人 echo、你也 echo ,是問 echo 知多少?( 2008-10-30 02:08 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=3#pid1482452[/url]
4) " "(雙引號) 與 ' '(單引號)差在哪?  (2008-10-30 02:07 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=4#pid1511745[/url]
5) var=value?export 前後差在哪? (2008-10-30 02:12 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=5#pid1544391[/url]
6) exec 跟 source 差在哪? (2008-10-30 02:17 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=6#pid1583329[/url]
7) ( ) 與 { } 差在哪?
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=6#pid1595135[/url]
8) $(( )) 與 $( ) 還有${ } 差在哪? (2008-10-30 02:20 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=7#pid1617953[/url]
9) $@ 與 $* 差在哪?
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=7#pid1628522[/url]
10) && 與 || 差在哪? (2008-10-30 02:21 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=7#pid1634118[/url]
11) > 與 < 差在哪? (2008-10-30 02:24 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=7#pid1636825[/url]
12) 你要 if 還是 case 呢? (2008-10-30 02:25最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=8#pid1679488[/url]
13) for what? while 與 until 差在哪? (2008-10-30 02:26最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=8#pid1692457[/url]

補充問題:
b1) [^ ] 跟 [! ] 差在哪?
Part-I(Wildcard): (2008-10-30 02:25 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=16#pid2930144[/url]
Part-II(Regular Expression): (2008-10-30 02:26 最後更新)
[url]http://bbs.chinaunix.net/viewthread.php?tid=218853&extra=&page=16#pid2934852[/url]


--------------
說明:
1) 歡迎大家補充/擴充問題。
2) 我接觸電腦中文名稱時是在台灣,因此一些術語或與大陸不同,請自行轉換。
3) 我會不定時"逐題"說明([color=red]以 Linux 上的 bash 為環境[/color])。同時,也會在任何時候進行無預警修改。請讀者自行留意。
4) 本人於本系列所發表的任文章均可自由以電子格式(非印刷)引用、修改、轉載,且不必註明出處(若能註明 CU 更佳)。
當然,若有錯漏或不當結果,本人也不負任何責任。
5) 若有人願意整理成冊且付印者,本人僅保留著作權,版權收益之 30% 須捐贈與 CU 論壇管理者,剩餘不究。

---------
建議參考討論:
1) shaoping0330 兄關於變量替換的補充:
(連結在改版後已經失效)

2) shaoping0330 兄關於 RE 的說明:
[url]http://bbs.chinaunix.net/forum/viewtopic.php?t=393964[/url]

3) 關於 nested subshell 的討論:
(連結在改版後已經失效)

4) 關於 IFS 的討論:
[url]http://bbs.chinaunix.net/forum/viewtopic.php?t=512925[/url]

---------
* 感謝 lkydeer 兄整理 word/pdf 版本方便大家参考:
[url]http://bbs.chinaunix.net/viewthread.php?tid=963890&extra=page%3D2[/url]

[[i] 本帖最后由 網中人 于 2008-11-4 02:12 编辑 [/i]]

2003-12-9 02:54 deeperpurple
shell 十三問?

感谢版主~~ 我也在学习Shell编程,开始打个好基础。

2003-12-9 07:24 admirer
shell 十三問?

很有“杀伤力”的问题,希望大家踊跃参与,共同商榷!

2003-12-9 09:01 飞灰橙
shell 十三問?

好问题!值得仔细琢磨琢磨...

2003-12-9 09:53 c1l2d3
shell 十三問?

晕了~~这些题我一个也说不清楚
:oops:  :oops:  :oops:

2003-12-9 10:17 forliving
shell 十三問?

只想知道答案。

2003-12-9 10:31 高山流云
shell 十三問?

关于第一个问题,什么是shell

作者:Rick Rummel


介绍
你可以做许多事情而不必知道它们实际上如何运作。比如,你不必懂得发动机燃烧的物理原理就可以开汽车。缺乏电子知识也不会阻止
你用CD机听音乐。不知道什么是Shell和它的工作原理,你还是可以使用UNIX。但是,知道这些你可以更好地利用UNIX。
一个UNIX系统有三种具有代表性的Shell可用:Bourne
shell,Korn shell,C shells。它们会在11,12,13章讨论。在这一章中,你会学到:

什么是Shell
Shell可以为你做什么
Shell和整个系统的关系



内核与Shell


坚果的壳保护其内部的核,同样一个UNIX
shell提供一个外设的保护层。当你启动一台基于UNIX的计算机时,UNIX的程序被调入计算机的内存里,直到你关机。这个程序叫做内
核(kernel),它执行许多底级和系统级的工作。内核有责任解释基本指令并将其送到处理器。内核也负责运行和调度进程,以及执行所
有的输入输出。内核是UNIX系统的心脏,内核有且只有一个。

你也许对内核职责的关键性有点迷惑,而内核指令同样的复杂和高技术性。为了对用户屏蔽内核的复杂性,也为了保护内核以免用户误操
作造成损害,在内核的周围建了一个外壳(shell)。用户向shell提出请求,shell解释并将请求传给内核。这一节剩下的部分解释这个外层
是如何建立的。

一旦内核调入内存,他就准备执行用户的请求。然而,用户首先得连接登录,然后发出请求。不管怎样,用户登录,内核必须知道用户是
谁以及如何与他通话。为了做到这点,内核调用两个特殊的程序,getty和login.对应每个用户的登录点--通常称为一个tty--内核调用
getty程序。这个过程被称为spawning(spawn原意是产卵)。getty显示一个登录提示,接着不断地监视通话点等待用户名的输入。当
getty取得任何输入时,它便调用login程序。login建立用户的身份并验证他登录的权利。login程序检查password(密码)文件。如果用
户输入的密码不正确,控制将从登录点返回到getty。如果正确,login调用password文件里用户条目中所记录的程序并将控制交给它。这
个程序也许是一个字处理软件或者是电子表格程序,不过一般是被称为shell的程序。

假设有四个用户已经登录进系统。这四个用户中,有两个正使用Bourne shell,一个使用Korn
shell,还有一个使用电子表格程序。每一个用户都得到一份shell的拷贝以服务它的请求,但是内核只有一个。使用shell不会阻碍用户使用
电子表格或别的程序,但那些程序是运行在活动的shell下的。shell是一个单一用户专用的程序,它在用户和UNIX内核之间提供了一个界
面。

你不必一定要使用shell来存取UNIX。上面的例子中,有个用户使用电子表格取代了shell。当这个用户登录进来时,电子表格程序启动。
当它退出电子表格程序时,他也就退出了系统。当强调安全性或者希望将用户与任何UNIX的界面屏蔽开时,这个技术挺有用。缺点是用
户不能使用mail或其他UNIX的功能。

因为login后可以执行任何程序--shell只是简单的一个程序--你就有可能编写自己的shell。事实上,三个独立开发的shell已经成为UNIX
标准的一部分。它们是:


Bourne shell,由Stephen Bourne开发
Korn shell,由David Korn开发
C shell,由Bill Joy开发

shell的多样性使你可以选择最适合你或者你感到最亲近的界面。



shell的功能



不过你选择哪个标准的shell并没有多大关系,因为三个shell都有相同的目的:在UNIX下为用户提供一个界面。为了达到这个目标,三个
shell都提供了相同的基本功能:


命令行解释功能
启动程序
输入输出重定向
管道连接
文件名置换
变量维护
环境控制
shell编程


命令行解释



当你登录进来,启动一个交互式的shell时,你会看到一个shell提示,通常是$,%或者#符号的形式。当你在提示符下敲进一行字符后,
shell就试图解释它。shell提示符下的输入有时被称为一个命令行。命令行的基本格式是
command arguments
命令名 参数(一个或多个))

command(命令)是可执行的UNIX命令,程序,实用工具,或shell程序。arguments(参数)被传递给执行程序。大多数的UNIX实
用程序要求参数有以下的格式:
option filenames
选项 文件名(一个或多个))

举个例子,在命令行下有

$ ls -l
file1 file2

在这个命令行中有三个参数传递给ls,第一个是个选项,剩下的两个是文件名。shell为内核所做的事情之一是减少不需要的信息。对于计
算机,空白(whit-espace)是一类无用信息;因此,有必要知道shell在遇到空白时做了些什么。空白由空格,水平制表符和换行符组成。
考虑这个例子:

$ echo part A part B part C

part A part B part C

这儿将命令行解释为有六个参数的echo命令并删除了参数之间的空白。假设如果你正在打印报告头想保留空白,你就得用引号将数据括起
来就象下面所示:

$echo part A part B part C

part A part B part C

单引号阻止shell检查引号里面。现在shell将这一行解释为带一个参数的echo命令,而这个参数正好是包含空白的字符串。

 

启动程序


当shell解释完命令行后,它就启动命令行中要求的程序。实际是内核执行这个程序。为了启动程序执行,shell在PATH环境变量指定的目
录中搜索可执行文件。当它找到这个文件,就启动一个子shell来运行程序。你应该知道子shell不必影响它父亲的环境设置而建立和操纵自
己的环境。比如一个子shell可以改变它的工作目录,当它运行完后,其父shell的工作目录仍保持不变。

 

输入输出重定向



shell在执行程序前进行重定向。考虑下面两个例子,其中使用wc单词统计工具统计有五行的数据文件:

$wc -l fivelines

5 fivelines

$wc -l 5

这里有一点微小的差异。在第一个例子中,wc知道它应该出去寻找名为fivelines的文件并对其进行操作。因为wc知道文件名,所以它将其
显示给用户。在第二个例子中,wc仅看到数据而不知道这些数据从那里来,因为shell做了定位和重定向数据到wc的工作,也因此wc无法
显示文件名。

 

管道连接

  管道是输入输出重定向的特例,它将一个命令的输出直接连到另一个命令的输入,因此管道也是在调用程序前建立的。考虑下面的命
令行:

$who|wc -l

5

shell没将who的输出显示到屏幕上,而是定向到wc的输入。

 

文件名置换

 


shell有责任进行文件名的替换。shell在执行程序前做替换。举个例子:

$echo
*

file1 file2 file3 file3x file4

这儿,星号被扩展为五个文件名,并被传递给echo作为五个参数。如果你想显示一个星号,你应该用引号将它括起来。

   

变量维护

  

shell有能力进行变量维护。变量是存储数据为将来所用的场所。用等号(=)可以给变量赋值。

$LOOKUP=/usr/mydir

在这里,shell建立一个LOOKUP变量,并将/usr/mydir赋给它。稍后,你可以在命令行上通过在变量名之前加$符号来使用变量值。考虑
这些例子:

$echo $LOOKUP

/usr/mydir

$echo LOOKUP

LOOKUP



C-shell的用户应该注意:C-shell中的赋值不同于Bourne和Korn
shell。C-shell使用set命令进行赋值。

$set LOOKUP =
/usr/mydir

注意在等号两边要加空格。



就象文件名的置换一样,变量名的置换也是在调用程序前进行。第二个例子省略了$符号。因此,shell只是简单地将字符串传递给echo作
参数。在变量替换中,变量的值取代了变量名。例如在:

$ls $LOOKUP/filename

用/usr/mydir/filename做参数调用ls。  

环境控制


当login程序调用你的shell时,shell对你的环境进行设置,其中包括你的home(家)目录,你使用的终端类型以及用来搜索可执行文件的
路径。环境被存储在环境变量中。举个例子,要改变终端类型,你需要改变TERM变量中的值,就象下面所示的:

$echo $TERM

vt 100

$TERM=ansi

$echo $TERM

ansi



注意在C-shell中,给环境变量赋值使用setenv命令。

%setenv TERM
vt100



shell编程

 


你已经看到shell可以用来解释命令行,维护变量,执行程序。另外shell还是一种编程语言。通过使用流程控制和条件判断来组合命令与变
量赋值,你就拥有了一个有力的编程工具。使用shell作为一门编程语言,你可以使重复的任务自动化,写报告,甚至你可以建立和操纵自
己的数据文件。



来源:[quote]http://www.linuxeden.com/edu/doctext.php?docid=1337[/quote]

2003-12-9 11:50 sd-feng
shell 十三問?

单引号‘’
取消除单引号以外的任何字符的特殊含义。如:echo  ‘my name is  $name’其结果为:my name is $name ,此时$只作为一个普通字符使用了。

双引号“”
取消除双引号、$号以及_号以外的所有字符的特殊含义

2003-12-9 11:51 sd-feng
shell 十三問?

输入转向符〈
用于指定输入的设备或文件。如:mail root〈message则将文件message 的内容发送给root。

输出转向符 〉
用于将输出发送到指定的设备或文件。如:lf 〉myfile 其结果是将lf的执行结果放到文件myfile中(同时清空文件中原有的数据),而不显示到屏幕上。

2003-12-9 11:56 sd-feng
shell 十三問?

&& 和 ||
其作用是使管道线有条件地执行。其使用方法为:
command1 && command2:当且仅当command1执行成功后才执行command2
command1 || command2:当且仅当command1执行失败后才执行command2

2003-12-9 14:12 網中人
shell 十三問?

1) 為何叫做 shell ?

在介紹 shell 是甚麼東西之前,不妨讓我們重新檢視使用者與電腦系統的關係:
        圖(FIXME)

我們知道電腦的運作不能離開硬體,但使用者卻無法直接對硬體作驅動,
硬體的驅動只能透過一個稱為"作業系統(Operating System)"的軟體來控管,
事實上,我們每天所談的 linux ,嚴格來說只是一個作業系統,我們稱之為"核心(kernel)"。
然而,從使用者的角度來說,使用者也沒辦法直接操作 kernel ,
而是透過 kernel 的"外殼"程式,也就是所謂的 shell ,來與 kernel 溝通。
這也正是 kernel 跟 shell 的形像命名關係。如圖:
                圖(FIXME)

從技術角度來說,shell 是一個使用者與系統的互動界面(interface),
主要是讓使用者透過命令行(command line)來使用系統以完成工作。
因此,shell 的最簡單的定義就是---命令解譯器(Command Interpreter):
        * 將使用者的命令翻譯給核心處理,
        * 同時,將核心處理結果翻譯給使用者。

每次當我們完成系統登入(log in),我們就取得一個互動模式的 shell ,也稱為 login shell 或 primary shell。
若從行程(process)角度來說,我們在 shell 所下達的命令,均是 shell 所產生的子行程。這現像,我們暫可稱之為 fork 。
如果是執行腳本(shell script)的話,腳本中的命令則是由另外一個非互動模式的子 shell (sub shell)來執行的。
也就是 primary shell 產生 sub shell 的行程,sub shell 再產生 script 中所有命令的行程。
(關於行程,我們日後有機會再補充。)

這裡,我們必須知道:kernel 與 shell 是不同的兩套軟體,而且都是可以被替換的:
        * 不同的作業系統使用不同的 kernel ,
        * 而在同一個 kernel 之上,也可使用不同的 shell 。
在 linux 的預設系統中,通常都可以找到好幾種不同的 shell ,且通常會被列於如下檔案裡:
        /etc/shells
不同的 shell 有著不同的功能,且也彼此各異、或說"大同小異"。
常見的 shell 主要分為兩大主流:
        sh:
                burne shell (sh)
                burne again shell (bash)
        csh:
                c shell (csh)
                tc shell (tcsh)
                korn shell (ksh)
        (FIXME)

大部份的 Linux 系統的預設 shell 都是 bash ,其原因大致如下兩點:
        * 自由軟體
        * 功能強大
bash 是 gnu project 最成功的產品之一,自推出以來深受廣大 Unix 用戶喜愛,
且也逐漸成為不少組織的系統標準。

2003-12-9 19:07 newince
shell 十三問?

台湾!看来领先我们的技术太多了。佩服!!!
大家努力答答看。

2003-12-9 23:15 admirer
shell 十三問?

[b]关于{}和()[/b]
[quote]1.{} 的用法
确认你有一个叫file和一个叫file1的变量。能够使用以下的语句给它们赋值:
$ file=this
$ file1=that
$echo $fileand$file1 寻找变量fileand,file1
sh: fileand: parameter not set
$ echo ${file} and $file1 寻找变量file,file1
thisandthat
花括号被用来区分变量名和周围的文本
2.()的用法
命令替代
语法:
$(command)
例子:
$pwd
/home/user2
$ curdir=$(pwd)
$ echo $curdir
/home/user2
$ cd /tmp
$ pwd
$ cd $curdir
$ pwd
/home/user2
命令替代用来替代一个命令和命令行输出。命令替代的标准语法,也是POSIX鼓励的一种语法是:$(command).
命令替代让你捕获一个命令的输出,用它作为另一个命令的参数,或是赋值给一个变量。象在变量替代中一样,命令替代的执行是在命令行开始之前完成的。当命令行输出包含回车换行,它们会被空格代替。
同变量替代相似,命令替代使用一个美元符号之后的用括号包围的一个命令。
所有有效的shell脚本都可以加入命令替代。Shell 扫描每行脚本,执行它发现的开始于一个开括号,结束与于一个闭括号的命令。
命令替代的另外一种格式是用反引号来环绕一个命令象:
`command`
它和$(command) 是等价的,并且这是Bourne Shell认证的唯一的形式。`command`形式可以用在POSIX的脚本中和Bourne Shell的脚本中。
命令替代通常是在将一个命令的输出赋给一个变量或以后的处理时使用。通常pwd命令将它的输出送到你的屏幕。当你执行以下的赋值语句:
$ curdir=$(pwd) 或 $ curdir=`pwd`
pwd 的输出被赋给变量 curdir。[/quote]

2003-12-10 22:22 config t
shell 十三問?

以前接触了一些台湾/香港软件和技术人员
其实并不是他们技术首先问题
而是他们很务实,简洁,而且最重要是应用得很适当,就是把一个简单的东西发挥它最大的用处

我最佩服他们这方面的思想

2003-12-11 09:35 labrun
shell 十三問?

出不了力,为你们支持一下。

2003-12-11 14:55 iamzoe
shell 十三問?

[quote="高山流云"][/quote]
我用了set在cshell里给变量赋值怎么不成功呀,我是小菜,大家多帮忙

2003-12-11 17:30 網中人
shell 十三問?

[quote][i]原帖由 "config t" 发表:[/i]
以前接触了一些台湾/香港软件和技术人员
其实并不是他们技术首先问题
而是他们很务实,简洁,而且最重要是应用得很适当,就是把一个简单的东西发挥它最大的用处

我最佩服他们这方面的思想[/quote]

怎麼我在台灣的感覺剛好相反呢?  ^_^

2003-12-12 02:55 網中人
shell 十三問?

2) shell prompt(PS1) 與 Carriage Return(CR) 的關係?

當你成功登錄進一個文字界面之後,大部份情形下,
你會在熒幕上看到一個不斷閃爍的方塊或底線(視不同版本而別),
我們稱之為*遊標*(cursor)。
遊標的作用就是告訴你接下來你從鍵盤輸入的按鍵所插入的位置,
且每輸入一鍵遊標便向右邊移動一個格子,若連續輸入太多的話,則自動接在下一行輸入。

假如你剛完成登錄還沒輸入任何按鍵之前,你所看到的遊標所在位置的同一行的左邊部份,
我們稱之為*提示符號*(prompt)。
提示符號的格式或因不同系統版本而各有不同,在 Linux 上,只需留意最接近遊標的一個可見的提示符號,通常是如下兩者之一:
        $:給一般使用者帳號使用
        #:給 root (管理員)帳號使用

事實上,shell prompt 的意思很簡單:
        * 是 shell 告訴使用者:您現在可以輸入命令行了。
我們可以說,使用者只有在得到 shell prompt 才能打命令行,
而 cursor 是指示鍵盤在命令行所輸入的位置,使用者每輸入一個鍵,cursor 就往後移動一格,
直到碰到命令行讀進 CR(Carriage Return,由 Enter 鍵產生)字符為止。
CR 的意思也很簡單:
        * 是使用者告訴 shell:老兄你可以執行我的命令行了。
嚴格來說:
        * 所謂的命令行,就是在 shell prompt 與 CR 字符之間所輸入的文字。
        (思考:為何我們這裡堅持使用 CR 字符而不說 Enter 鍵呢?答案在後面的學習中揭曉。)

不同的命令可接受的命令行格式或有不同,一般情況下,一個標準的命令行格式為如下所列:
        command-name options argument

若從技術細節來看,shell 會依據 IFS(Internal Field Seperator) 將 command line 所輸入的文字給拆解為"字段"(word)。
然後再針對特殊字符(meta)先作處理,最後再重組整行 command line 。
(注意:請務必理解上兩句話的意思,我們日後的學習中會常回到這裡思考。)

其中的 IFS 是 shell 預設使用的欄位分隔符號,可以由一個及多個如下按鍵組成:
        * 空白鍵(White Space)
        * 表格鍵(Tab)
        * 回車鍵(Enter)

系統可接受的命令名稱(command-name)可以從如下途逕獲得:
        * 明確路逕所指定的外部命令
        * 命令別名(alias)
        * 自定功能(function)
        * shell 內建命令(built-in)
        * $PATH 之下的外部命令
每一個命令行均必需含用命令名稱,這是不能缺少的。

[[i] 本帖最后由 網中人 于 2008-10-30 02:05 编辑 [/i]]

2003-12-12 09:08 飞灰橙
shell 十三問?

说得好,请继续!

2003-12-12 10:50 gunguymadman007
shell 十三問?

顶   
看来买书学习这条法子是不行的了  
书只能领你入门   
要想登堂入室还要多在论坛上混啊

页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: shell 十三問?