歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 每天一個Linux命令(20)find命令_exec參數

每天一個Linux命令(20)find命令_exec參數

日期:2017/3/3 12:38:54   编辑:Linux技術

find命令的exec參數,用於find查找命令完成以後的後續操作。[b] (1)用法:[/b]

用法: [find命令] [-exec 其他命令 {} \;] [b] (2)功能:[/b]

功能:-exec find命令對匹配的文件執行該參數所給出的其他linux命令。[b] (3)-exec的解釋:[/b]

-exec參數後面跟的是command命令,它的終止是以;為結束標志的,所以這句命令後面的分號是不可缺少的 考慮到各個系統中分號會有不同的意義,所以前面加反斜槓。 {} 花括號代表前面find查找出來的文件名。

[b] (4)實例:[/b] 1)[root@localhost Documents]# find -type f -exec ls -l {} \;              將查找出來的結果用ls -l命令列出

[root@localhost sunjimeng]# cd Documents
[root@localhost Documents]# ll                    //ll命令等價於 ls -l
總用量 20
drwxr-xr-x. 2 root root  71 5月  17 04:18 findDir
-rw-r--r--. 1 root root 664 5月   9 07:59 head_text
-rw-r--r--. 1 root root  45 5月   9 08:15 less1
-rw-r--r--. 1 root root  57 5月   9 08:16 less2
-rw-r--r--. 1 root root   0 5月  15 18:21 newlocate
-rw-r--r--. 1 root root 259 5月  12 21:53 tail_text
-rw-r--r--. 1 root root 216 5月  12 22:24 tempory
-rw-r--r--. 1 root root   0 5月  15 18:34 uText
[root@localhost Documents]# find -type f -exec ls -l {} \;   //這裡與直接執行ls -l命令不同的是,find命令會遞歸地將所有當前要查詢的文件的子目錄進行遍歷,將每個後代文件均輸出。
-rw-r--r--. 1 root root 45 5月   9 08:15 ./less1
-rw-r--r--. 1 root root 57 5月   9 08:16 ./less2
-rw-r--r--. 1 root root 664 5月   9 07:59 ./head_text
-rw-r--r--. 1 root root 259 5月  12 21:53 ./tail_text
-rw-r--r--. 1 root root 216 5月  12 22:24 ./tempory
-rw-r--r--. 1 root root 0 5月  15 18:21 ./newlocate
-rw-r--r--. 1 root root 0 5月  15 18:34 ./uText               //只輸出文件,卻沒有輸出文件夾
-rw-r--r--. 1 root root 0 5月  17 03:50 ./findDir/t1.txt
-rw-r--r--. 1 root root 0 5月  17 04:02 ./findDir/T1.txt
-rw-r--r--. 1 root root 0 5月  17 04:02 ./findDir/T2.txt
-rw-r--r--. 1 root root 0 5月  17 04:18 ./findDir/p1.pdf
-rw-r--r--. 1 root root 0 5月  17 04:18 ./findDir/p2.pdf
[root@localhost Documents]#
-type d與-type f的區別:

[root@localhost Documents]# find -type d -exec ls -l {} \;     //這裡沒有顯示相對的路徑
總用量 20
drwxr-xr-x. 2 root root  71 5月  17 04:18 findDir
-rw-r--r--. 1 root root 664 5月   9 07:59 head_text
-rw-r--r--. 1 root root  45 5月   9 08:15 less1
-rw-r--r--. 1 root root  57 5月   9 08:16 less2
-rw-r--r--. 1 root root   0 5月  15 18:21 newlocate
-rw-r--r--. 1 root root 259 5月  12 21:53 tail_text
-rw-r--r--. 1 root root 216 5月  12 22:24 tempory
-rw-r--r--. 1 root root   0 5月  15 18:34 uText
總用量 0
-rw-r--r--. 1 root root 0 5月  17 04:18 p1.pdf
-rw-r--r--. 1 root root 0 5月  17 04:18 p2.pdf
-rw-r--r--. 1 root root 0 5月  17 03:50 t1.txt
-rw-r--r--. 1 root root 0 5月  17 04:02 T1.txt
-rw-r--r--. 1 root root 0 5月  17 04:02 T2.txt
2)[root@localhost Document]# find . -type f -mtime +10 -exec rm -i {} \;        刪除10天以外修改過的文件,刪除時給出提醒

[root@localhost Document]# find . -type f -mtime +14 -exec rm -i {} \;      由+14給出後沒有反應,而給參數+10之後有反應,可知這些文件是10到14天以前建立或修改過的
[root@localhost Document]# find . -type f -mtime +10 -exec rm -i {} \;
rm:是否刪除普通空文件 "./newDir/text1"?n
rm:是否刪除普通空文件 "./newDir/text2"?n
rm:是否刪除普通空文件 "./text1/newDir/text1"?n
rm:是否刪除普通空文件 "./text1/newDir/text2"?n
rm:是否刪除普通空文件 "./text2/newDir/text1"?n
rm:是否刪除普通空文件 "./text2/newDir/text2"?n
rm:是否刪除普通空文件 "./text3/text1"?n
rm:是否刪除普通空文件 "./text3/text2"?n
rm:是否刪除普通空文件 "./text4/text1"?n
rm:是否刪除普通空文件 "./text4/text2"?n
rm:是否刪除普通空文件 "./mytext"?n
rm:是否刪除普通空文件 "./mytext.txt"?n
3)[root@localhost Document]# find . -type f -mtime +10 -ok rm {} \;           另一種方法實現刪除時的交互

[root@localhost Document]# find . -type f -mtime +10 -ok rm {} \;
< rm ... ./newDir/text1 > ? n
< rm ... ./newDir/text2 > ? n
< rm ... ./text1/newDir/text1 > ? n
< rm ... ./text1/newDir/text2 > ? n
< rm ... ./text2/newDir/text1 > ? n
< rm ... ./text2/newDir/text2 > ? n
< rm ... ./text3/text1 > ? n
< rm ... ./text3/text2 > ? n
< rm ... ./text4/text1 > ? n
< rm ... ./text4/text2 > ? n
< rm ... ./mytext > ? n
< rm ... ./mytext.txt > ? n
4)[root@localhost Document]# find /etc -name "passwd*" -exec grep "root" {} \;      查看查詢出來的文件中有沒有root用戶

[root@localhost Document]# ll                          //此目錄下有用戶文件,也有root文件
總用量 0
-rw-rw-r--. 1 sunjimeng sunjimeng  0 5月  18 02:24 grepTest
-rw-r--r--. 1 root      root       0 5月   6 22:15 mytext
-rw-r--r--. 1 root      root       0 5月   6 22:15 mytext.txt
drwxr-xr-x. 2 root      root      30 5月   6 22:02 newDir
-rw-rw-r--. 1 sunjimeng sunjimeng  0 5月  18 02:34 userfile
[root@localhost Document]# find /etc -name "passwd*" -exec grep "root" {} \;         //用grep命令查看在這些文件中是否存在一個root用戶。(不太清楚什麼意思)
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost Document]# find . -type f -exec grep "root" {} \;            //然而用這個命令,一點反應沒有!
5)[root@localhost Document]# find . -name "mv*" -exec mv {} newDir \;          將查詢到的內容移動到newDir目錄下

[root@localhost Document]# ls
newDir
[root@localhost Document]# touch {mvt1.txt,mvt2.txt,mvt3.txt}
[root@localhost Document]# find . -name "mv*" -exec ls -l {} \;
-rw-r--r--. 1 root root 0 5月  18 02:46 ./mvt1.txt
-rw-r--r--. 1 root root 0 5月  18 02:46 ./mvt2.txt
-rw-r--r--. 1 root root 0 5月  18 02:46 ./mvt3.txt
[root@localhost Document]# find . -name "mv*" -exec mv newDir {} \;  //注意順序不要弄錯
mv: 無法以目錄"newDir" 來覆蓋非目錄"./mvt1.txt"
mv: 無法以目錄"newDir" 來覆蓋非目錄"./mvt2.txt"
mv: 無法以目錄"newDir" 來覆蓋非目錄"./mvt3.txt"
[root@localhost Document]# find . -name "mv*" -exec mv {} newDir \;    //mv命令將前面的文件集移動到後面的文件夾中
[root@localhost Document]# ll
總用量 0
drwxr-xr-x. 2 root root 51 5月  18 02:47 newDir
[root@localhost Document]# ls -l ./newDir
總用量 0
-rw-r--r--. 1 root root 0 5月  18 02:46 mvt1.txt
-rw-r--r--. 1 root root 0 5月  18 02:46 mvt2.txt
-rw-r--r--. 1 root root 0 5月  18 02:46 mvt3.txt
6)[root@localhost sunjimeng]# find . -name "t*.txt" -mtime -1 -exec cat {} \; > ./Document/all.txt   合並查詢到的多個文件的文本內容到一個新的文件

[root@localhost Document]# ll            //查看當前目錄
總用量 0
drwxr-xr-x. 2 root root 51 5月  18 02:47 newDir
[root@localhost Document]# cat >t1.txt <<EOF     //新建t1.txt
> this is t1.txt!
> I'm testing -exec option!
> EOF
[root@localhost Document]# cat >t2.txt <<EOF     //新建t2.txt
> this is t2.txt!
> I'm testing -exec optioin!
> EOF
[root@localhost Document]# cd ../
[root@localhost sunjimeng]# find -name "t*.txt" -exec ls -l {} \;             //查出了很多,前幾項紅的不是我們要的
-rw-rw-r--. 1 sunjimeng sunjimeng 58 5月   4 21:45 ./.local/share/Trash/files/test1.txt
-rw-rw-r--. 1 sunjimeng sunjimeng 61 5月   4 21:46 ./.local/share/Trash/files/test2.txt
-rw-rw-r--. 1 sunjimeng sunjimeng 61 5月   4 21:47 ./.local/share/Trash/files/test3.txt-rw-r--r--. 1 root root 42 5月  18 02:53 ./Document/t1.txt
-rw-r--r--. 1 root root 43 5月  18 02:54 ./Document/t2.txt
[root@localhost sunjimeng]# find -name "t*.txt" -mtime -1 -exec ls -l {} \;   //加上日期限制為一天以內修改過的之後,顯示正確的文件-rw-r--r--. 1 root root 42 5月  18 02:53 ./Document/t1.txt
-rw-r--r--. 1 root root 43 5月  18 02:54 ./Document/t2.txt
[root@localhost sunjimeng]# find . -name "t*.txt" -mtime -1 -exec cat {} \; > ./Document/all.txt   //將文件輸出到當前子目錄Document下的all.txt文件中,如果不存在則創建
[root@localhost sunjimeng]# cat ./Document/all.txt
this is t1.txt!
I'm testing -exec option!
this is t2.txt!
I'm testing -exec optioin!
7)[root@localhost sunjimeng]# find ./Documents -type f -name "*.txt" -exec printf "File: %s\n" {} \;    將查詢到的文件當作字符數組,用類似c語言的printf的形式控制格式輸出

[root@localhost sunjimeng]# find ./Documents -type f -name "*.txt" -exec printf "File: %s\n" {} \; 
File: ./Documents/findDir/t1.txt
File: ./Documents/findDir/T1.txt
File: ./Documents/findDir/T2.txt
[root@localhost sunjimeng]# find ./Documents -type f -name "*.txt" -exec printf "File: %s\n\n" {} \;  //也可以多加一個\n
File: ./Documents/findDir/t1.txt

File: ./Documents/findDir/T1.txt

File: ./Documents/findDir/T2.txt

[root@localhost sunjimeng]#
(4)其他:

Linux中exec命令相關:

  bash shell的命令分為兩類:外部命令和內部命令。外部命令是通過系統調用或獨立的程序實現的,如sed、awk等等。內部命令是由特殊的文件格式(.def)所實現,如cd、history、exec等等。 1. 系統調用exec是以新的進程去代替原來的進程,但進程的PID保持不變。因此,可以這樣認為,exec系統調用並沒有創建新的進程,只是替換了原來進程上下文的內容。原進程的代碼段,數據段,堆棧段被新的進程所代替。

fork的概念 fork是linux的系統調用,用來創建子進程(child process)。子進程是父進程(parent process)的一個副本,從父進程那裡獲得一定的資源分配以及繼承父進程的環境。子進程與父進程唯一不同的地方在於pid(process id)。

一個進程主要包括以下幾個方面的內容: (1)一個可以執行的程序

(2) 與進程相關聯的全部數據(包括變量,內存,緩沖區) (3)程序上下文(程序計數器PC,保存程序執行的位置)

2. exec是一個函數簇,由6個函數組成,分別是以excl和execv打頭的。 執行exec系統調用,一般都是這樣,用fork()函數新建立一個進程,然後讓進程去執行exec調用。我們知道,在fork()建立 新進程之後,父進各與子進程共享代碼段,但數據空間是分開的,但父進程會把自己數據空間的內容copy到子進程中去,還有上 下文也會copy到子進程中去。而為了提高效率,采用一種寫時copy的策略,即創建子進程的時候,並不copy父進程的地址空間, 父子進程擁有共同的地址空間,只有當子進程需要寫入數據時(如向緩沖區寫入數據),這時候會復制地址空間,復制緩沖區到子 進程中去。從而父子進程擁有獨立的地址空間。而對於fork()之後執行exec後,這種策略能夠很好的提高效率,如果一開始就 copy,那麼exec之後,子進程的數據會被放棄,被新的進程所代替。

Copyright © Linux教程網 All Rights Reserved