亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

沒用的貓?

沒用的貓?

茅侃侃 2019-05-30 16:02:58
沒用的貓?這可能在許多常見問題中-而不是使用:cat file | command(這被稱為對CAT的無用使用),正確的方式應該是:command < file在第二,“正確”的方式-操作系統不需要產生額外的進程。盡管我知道這一點,但我繼續使用無用的貓有兩個原因。更美觀-我喜歡數據只從左向右一致移動。而且更容易替換cat用別的東西(gzcat, echo,添加第二個文件或插入新篩選器(pv, mbuffer, grep ...).我“覺得”在某些情況下可能會更快。更快,因為有兩個進程,第一個(cat)閱讀,第二個做任何事情。它們可以并行運行,這意味著有時執行速度更快。我的邏輯正確嗎(第二個原因)?
查看完整描述

3 回答

?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

直到今天我才意識到這個獎項,當時一些菜鳥試圖將UUOC找我的答案之一。那是一個cat file.txt | grep foo | cut ... | cut ...。我給了他一個想法,然后訪問了他給我的鏈接,他提到了這個獎項的來源和這樣做的做法。進一步的研究使我想到了這個問題。有些遺憾的是,盡管有意識地考慮,但沒有一個答案包括我的理由。

我本不想在回應他時采取防御的態度。畢竟,在我年輕的時候,我會把命令寫成grep foo file.txt | cut ... | cut ...因為無論你做什么grep我們學習了文件參數的位置,它已經知道第一個是模式,而后面的是文件名。

這是一個有意識的選擇cat當我回答這個問題時,部分原因是“品味好”(用LinusTorvalds的話來說),但主要是為了一個令人信服的功能原因。

后一個原因更重要,所以我會先說出來。當我提供管道作為解決方案時,我希望它是可重用的。很可能會在另一條管道的末端添加一條管道,或將其拼接到另一條管道中。在這種情況下,帶有grep文件參數的grep會破壞可重用性,而且很可能會這樣做。靜默如果文件參數存在,則沒有錯誤消息。I.,即grep foo xyz | grep bar xyz | wc會給你多少行xyzbar當您期望包含兩者的行數時foobar。在使用之前,必須將參數更改為管道中的命令很容易出錯。再加上沉默失敗的可能性,它就變成了一種特別陰險的做法。

前一個原因也并非不重要,因為“有眼光“僅僅是直覺上的潛意識的理由,像上面的沉默失敗,你無法想到的時候,當某個人需要教育時,說”但那貓不是無用的“。

但是,我也會努力使我提到的前一個“好品味”的原因有意識。這與Unix的正交設計精神有關。grepcutlsgrep。所以至少grep foo file1 file2 file3違背了設計精神。做這件事的正交方法是cat file1 file2 file3 | grep foo?,F在,grep foo file1只是一個特例grep foo file1 file2 file3如果你不這樣對待它,你至少是在消耗大腦的時鐘周期,試圖避免無用的貓獎。

這就引出了我們的論點grep foo file1 file2 file3正在連接,而且cat串連,所以它是適當的cat file1 file2 file3但因為cat沒有連接到cat file1 | grep foo因此我們違背了cat以及萬能的Unix。如果是這樣的話,那么Unix將需要一個不同的命令來讀取一個文件的輸出并將其吐出到stdout(而不是對其進行分頁,也不只是一個純的stdout)。所以你會遇到你說的那種情況cat file1 file2或者你說dog file1認真地記住要避免cat file1為了避免獲獎,同時也要避免dog file1 file2因為希望…的設計dog如果指定多個文件,則會引發錯誤。

希望在這一點上,您同情unix設計器沒有包含一個單獨的命令來向stdout吐出一個文件,同時還命名了cat而不是給它取別的名字。<edit>刪除不正確的注釋<事實上,<是一種高效的不復制工具,可以將文件吐出到stdout,您可以將其定位在管道的開頭,因此unix設計器確實包含了一些專門用于此的內容。</edit>

下一個問題是,為什么命令只是吐出一個文件或將幾個文件連在一起,而不進行任何進一步的處理,這是很重要的呢?原因之一是避免讓每個在標準輸入上操作的Unix命令知道如何解析至少一個命令行文件參數,并在存在時將其用作輸入。第二個原因是避免用戶必須記?。?A)文件名參數的去處;(B)如上所述,避免沉默的管道錯誤。

這就引出了為什么grep確實有額外的邏輯。其基本原理是允許用戶流暢地使用頻繁使用的命令和單槍匹馬基礎(而不是管道)。這是一個小妥協的正交性,以顯著提高可用性。并不是所有的命令都是這樣設計的,不經常使用的命令應該完全避免文件參數的額外邏輯(記住,額外的邏輯會導致不必要的脆弱性(bug的可能性)。例外情況是允許文件參數,如grep。(順便提一下,請注意ls有一個完全不同的理由不僅接受,而且幾乎需要文件參數)

最后,本可以做得更好的是,如果這樣的特殊命令grep(但不一定ls)如果指定文件參數時標準輸入也可用,則生成錯誤。


查看完整回答
反對 回復 2019-05-30
?
慕妹3146593

TA貢獻1820條經驗 獲得超9個贊

不!

首先,在什么地方發生重定向并不重要。因此,如果您喜歡將方向重定向到命令的左邊,那很好:

<?somefile?command

是相同的

command?<?somefile

第二,有n+1進程和子外殼在使用管道時發生。這是最明顯較慢的。在某些情況下n應該是零(例如,當您重定向到shell內置的時候),所以使用cat您正在添加一個完全不必要的新過程。

一般說來,每當你發現自己在使用管道時,就應該花30秒的時間來看看你是否能消除它。(但可能不值得花費超過30秒的時間。)下面是一些管道和過程經常被不必要地使用的例子:

for?word?in?$(cat?somefile);?…?#?for?word?in?$(<somefile);?…?(or?better?yet,?while?read?<?somefile)grep?something?|?
awk?stuff;?#?awk?'/something/?stuff'?(similar?for?sed)echo?something?|?command;?#?command?<<<?
something?(although?echo?would?be?necessary?for?pure?POSIX)


查看完整回答
反對 回復 2019-05-30
  • 3 回答
  • 0 關注
  • 656 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號