1. 程式人生 > >shell之輸入輸出重定向

shell之輸入輸出重定向

1.shell的簡介:

     (1) 在電腦科學中,Shell俗稱殼(用來區別於核),是指“提供使用者使用介面”的軟體(命令解析器)。

它類似於DOS下的和後來的cmd.exe。它接收使用者命令,然後呼叫相應的應用程式。Shell既是一種命令語言,又是

一種程式設計語言。作為命令語言,它互動式解釋和執行使用者輸入的命令或者自動地解釋和執行預先設定好的一連串

的命令;作為程式設計語言,它定義了各種變數和引數,並提供了許多在高階語言中才具有的控制結構,包括迴圈和

分支。  在排序演算法中,Shell是希爾排序的名稱。 傳統意義上的shell指的是命令列式的shell,以後如果不特別注

明,shell是指命令列式的shell。

  文字作業系統與外部最主要的介面就叫做shell。shell是作業系統最外面的一層。shell管理你與作業系統之間的

互:等待你輸入,向作業系統解釋你的輸入,並且處理各種各樣的作業系統的輸出結果。shell提供了你與操作

間通訊的方式。這種通訊可以以互動方式(從鍵盤輸入,並且可以立即得到響應),或者以shell script(非

互)方式執行。shell script是放在檔案中的一串shell和作業系統命令,它們可以被重複使用。本質上,shell 

script是命令列命令簡單的組合到一個檔案裡面。Shell指令碼和程式語言很相似,也有變數和流程控制語句,但

Shell指令碼是解釋執行的,不需要編譯,Shell程式從指令碼中一行一行讀取並執行這些命令,相當於一個使用者把指令碼

中的命令一行一行敲到Shell提示符下執行。

Shell有兩種執行命令的方式:

  • 互動式(Interactive):解釋執行使用者的命令,使用者輸入一條命令,Shell就解釋執行一條。
  • 批處理(Batch):使用者事先寫一個Shell指令碼(Script),其中有很多條命令,讓Shell一次把這些命令執行完,而不必一條一條地敲命令。

互動式模式就是shell等待你的輸入,並且執行你提交的命令。這種模式被稱作互動式是因為shell與使用者進行交

互。這種模式也是大多數使用者非常熟悉的:登入、執行一些命令、簽退。當你簽退後,shell也終止了。shell也可

以執行在另外一種模式:批處理(非互動式)模式。在這種模式下,shell不與你進行互動,而是讀取存放在檔案

中的命令,並且執行它們。當它讀到檔案的結尾,shell也就終止了。

(2)命令描述

shell 命令重新初始化使用者的登入會話。當給出該命令時,就會重新設定程序的控制終端的埠特徵,並取消對端

口的所有訪問。然後 shell 命令為使用者把程序憑證和環境重新設定為預設值,並執行使用者的初始程式。根據呼叫進

程的登入使用者標識建立所有的憑證和環境。

注:shell 命令不會重新設定使用者的登入標識

安全性

訪問控制:該命令應該被 setuid 為 root 使用者,以重新設定使用者的程序憑證、授權執行(x)訪問所有使用者。該命

令應該具有可信計算庫屬性。

(3)說明

如果Shell 函式成功地執行了所要執行的檔案,則它會返回程式的任務 ID。任務 ID 是一個唯一的數值,用來指明

正在執行的程式。如果 Shell 函式不能開啟命名的程式,則會產生錯誤。

注意 預設情況下,Shell 函式是以非同步方式來執行其它程式的。也就是說,用Shell 啟動的程式可能還沒有完成執

行過程,就已經執行到 Shell 函式之後的語句。

2.重定向

     Linux重定向以前就提及過,現在在簡單介紹一下,它是指修改原來預設的一些東西,對原來系統命令的預設執行方式進行改變,比如說簡單的我不想看到在顯示器的輸出而是希望輸出到某一檔案中就可以通過Linux重定向來進行這項工作。Linux預設輸入是鍵盤,輸出是顯示器。你可以用重定向來改變這些設定。比如用wc命令的時候本來是要手動輸入一篇文字來計算字元數的,用了重定向後可以直接把一個已經寫好的檔案用‘<’指向這條命令,就直接可以統計這個檔案的字元數等了。輸出也是一樣,你可以把螢幕輸出重定向到一個檔案裡,再到檔案裡去看結果。重定向操作符可以用來將命令輸入和輸出資料流從預設位置重定向到其他位置,其輸入或輸出資料流的位置稱為控制代碼;常見的控制代碼有三種,當然控制代碼可以自行擴充套件,一般的OS都提供類似的功能。控制代碼 控制代碼代號 控制代碼描述

STDIN 0 鍵盤輸入

STDOUT 1 輸出資訊到提示符視窗

STDERR 2 輸出錯誤資訊到提示符視窗

3、用fork建立子程序後執行的是和父程序相同的程式(但有可能執行不同的程式碼分支),子程序往往要呼叫一種exec函式以執行另一個程式。當程序呼叫一種exec函式時,該程序的使用者空間程式碼和資料完全被新程式替換,從新程式的啟動例程開始執行。呼叫exec並不建立新程序,所以呼叫exec前後該程序的id並未改變。   以下有六種以exec開頭的函式,統稱exec函式 #include<unistd.h> int execl(const char *path,const char *arg,...); int execlp(const char *file,const char *arg,...); int execle(const char *path,const char *arg,...,char * const envp[]); int execv(const char *path,char* const argv[]); int execvp(const char *file,char *const argv[]); int execve(const char *path,char *const argv[],char *const envp[]); 這些函式如果呼叫成功則載入新的程式從啟動程式碼開始執行,不再返回,如果調用出錯則 返回-1, 所以exec函式只有出錯的返回值而沒有成功的返回值。 說明: 1)不帶字母p (表示path)的exec函式 第一個引數必須是程式的相對路徑或絕對路徑,例如"/bin/ls"或"./a.out",而不能 是"ls"或"a.out"。對於帶字母p的函式: 如果引數中包含/,則將其視為路徑名。 否則視為不帶路徑的程式名,在PATH環境變數的目錄列表中搜索這個程式。 2)帶有字母l( 表示list)的exec函式要求將新程式的每個命令列引數都當作一個引數傳給它,命令列 引數的個數是可變的,因此函式原型中有...,...中的最後一個可變引數應該是NULL, 起sentinel的作用。 3)帶有字母v( 表示vector)的函式,則應該先構造一個指向各引數的指標數 組,然後將該陣列的首地址當作引數傳給它,陣列中的最後一個指標也應該是NULL,就像main函式 的argv引數或者環境變量表一樣。 4)對於以e (表示environment)結尾的exec函式,可以把一份新的環境變量表傳給它,其他exec函式 仍使用當前的環境變量表執行新程式。 exec呼叫舉例如下:

char* cons ps_argv[]={"ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL};

char * const ps_envp[]={"PATH=/bin/usr/bin","TERM=console",NULL};

execl("/bin/ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL);

execv("/bin/ps",ps_argv);

execle("/bin/ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL,ps_envp);

execv("/bin/ps",ps_argv,ps_envp);

execlp("ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL);

execvp("ps",ps_argv);

事實上,只有execve是真正的系統呼叫,其它五個函式最終都呼叫execve.

程式碼實現:


看一下執行的結果: