0.前言及文章標題截圖
本文主要針對芯片驗證工作中常用的linux知識做了一個總結和梳理,內容雖然比較基礎,但確實是非常實用。全文8000多字,為了方便大家閱讀和查閱,我把文章的目錄截圖放下面。如果您是老手,看看目錄是不是都掌握了;如果您是新手,也不用焦慮,山高千仞,只登一步。
1.shell相關
作為一名芯片驗證工程師,幾乎每天都在跟shell打交道,如果沒有這些基本功,出現一點問題就找IT或同事幫忙,不僅影響工作效率,而且還可能會被嚴重鄙視的。
1.1查看所有的shell:cat /etc/shells
1.2查看當前使用的shell:
echo$SHELL,是非常不靠譜的;env| grep SHELL,更加的不靠譜的;echo $$ 得到process_id,然后ps -ef | grep process_id, 也是不靠譜的;
1.2.1 最簡單的命令:echo $0
下面介紹一下$0,在linux中,$0表示當前運行的進程名稱。大多數情況下使用echo $0來查詢當前使用的SHELL是最簡單的方法。
但是,echo $0,并不是100%靠譜的。
1.2.2最靠譜的命令:ps -p “$$”
通過 $$ 獲取當前 shell 實例的 PID ,然后通過 ps 命令尋找該 PID所對應的進程。結果中的 CMD 列,會列出當前 shell 程序的名稱。
1.3shell間的切換
1.3.1切換到bash
在terminal中直接輸入:bash即可。
1.3.2切換到csh
在terminal中直接輸入:csh即可。
1.3.3切換到ksh
在terminal中直接輸入:ksh即可。
如果 ~/.bash_profile中有export PS1='[u@h w]$',那么bash就不能切換到csh
1.4shell中顯示全路徑
1.4.1bash中顯示全路徑
如下圖所示,在~/.bashrc文件中,添加下面截圖中的內容。
這個命令提示符格式是由PS1這個環境變量控制的,所以我們可以通過修改這個變量來達到我們的目的。
補充:PS1各個字段的含義如下:
u :當前用戶的賬號名稱;
h :僅取主機的第一個名字,如icer.linux,則為icer,.linux則被省略;
d :代表日期,格式為weekday month date,例如:”Mon Aug 1”
:顯示時間為24小時格式,如:HH:MM:SS
v :BASH的版本信息
w :完整的工作目錄名稱。家目錄會以 ~代替
W :利用basename取得工作目錄名稱,所以只會列出最后一個目錄
$ :提示字符,如果是root時,提示符為:# ,普通用戶則為:$
1.4.2csh中顯示全路徑
如下圖所示,在~/.cshrc文件中,添加下面截圖中的內容。
1.5basename[感謝關注微信公眾號《芯片驗證日記》]
有些項目的腳本中,經常會出現basename,具體的用法可以通過:man basename
或者basename –help查看解釋,還有例子,非常友好。
basename可以獲取末尾路徑名或文件名
basename可以獲取末尾目錄名或者文件名:
1.6$0/$1-9/$#/$?/$*/$@/$!/$-/$IFS的用法
為什么會詳細地介紹下面這些奇怪的符號?作為一名芯片驗證工程師,經常會接觸到各種各樣的shell腳本,這些可都是芯片驗證工作必需的基本功呀!
1.6.1 $0 :腳本名
返回當前執行的shell腳本的名稱。
1.6.2 $1-$9 :分別代表第1-9個參數
分別代表腳本執行命令的第1個參數、第2個參數……第9個參數。
1.6.3$# :表示參數的個數。
執行腳本的結果:
1.6.4$* :表示所有參數
1.6.5$@ :表示所有參數
1.6.6$* 和 $@ 的區別:
區別在于,如何將參數作為單個字符串或多個獨立字符串進行處理。
$*會把所有的參數解釋成一個單詞(單個字符串),即每個參數之間不會加上空格,全部組合成一個字符串,用"IFS"(默認是空格)分隔。所以,將*放在雙引號里,預處理$符號,保持長字符串的完整性。
$@會把所有的參數看成是獨立的單詞(多個獨立的字符串),即每個參數之間加上空格,將每個參數作為一個獨立的字符串處理。
試驗代碼,如下圖所示:
運行結果,如下圖所示:
從上面的實驗可以看出,使用?時,所有參數都解釋為單個字符串,由空格分隔。而使用@時,每個參數都被解釋為一個單獨的字符串,并獨立處理。在大多數情況下,使用$@是更加靈活和安全的選項,因為它可以獨立處理每個參數,而不會將它們合并為單個字符串。
1.6.7$? :上一個命令的退出狀態碼
輸出結果0,表示上一個命令執行成功。
1.6.8$$ :當前進程ID號
獲取當前正在運行的Shell腳本的進程ID(PID)。使用$$變量時,需要注意它只能獲取當前Shell腳本的PID而不能獲取任何子進程或后臺任務的PID。
測試代碼,如下圖所示:
運行結果,如下圖所示:
1.6.9 $! :最近一次在后臺運行的進程的PID號
在LinuxShell腳本中,!是一個特殊變量,用于獲取最近一次在后臺運行進程的PID號(進程ID號)。! 通常用于在腳本中啟動后臺進程,并且需要獲取后臺進程的PID號。
測試代碼,如下圖所示:
運行結果,如下圖所示:
1.6.10$- :獲取當前Shell的選項標志(Option Flags)
選項標志是Shell用來控制其行為的一些特殊設置。$-可以用來獲取當前Shell所使用的選項標志,通常應用于Shell腳本的調試中,可以幫助我們診斷問題。
上述輸出中,選項標志中包含了5個字符,分別表示以下內容:
h:bash shell啟用hash命令時將完成命令名和緩存條目之間的HASH值打印到標準錯誤輸出中;
i:交互模式運行,即標準輸入與終端相連;
m:啟用作業控制功能;
B:啟用Brace Expansion(花括號擴展)機制;
H:Shell擴展歷史記錄功能,尋找法:$HOME/.bash_history,如果該文件不存在則新建一個。
1.6.11$IFS :指定Shell腳本中的字段分隔符
字段分隔符是將一行輸入或輸出按照不同的字段拆分開來并存儲在不同的變量中的標記。默認情況下,$IFS的值為空格,制表符和換行符。但是,我們可以將其設置為其他的分隔符來滿足特定的需求。
下圖中的腳本,通過read命令讀取一行輸入,并通過將$IFS設置為逗號來將輸入行分隔成不同的變量。最后,使用for循環按順序輸出不同的變量。
這是一個非常有用的用法,可以將一行以逗號或其他字符分隔的值按分隔符分成不同的變量,進一步處理這些變量值。
2.系統查詢相關[感謝關注微信公眾號《芯片驗證日記》]
為什么會介紹這些命令?因為有些eda軟件對操作系統OS是有依賴性的,當eda軟件出現一些很怪異現象的時候,也許是軟件版本和OS不兼容導致的,這時候可以查一下eda軟件的releasenote,然后對比一下os信息,看看是否匹配。
2.1lsb_release -a
查看當前Linux 系統完整的版本信息,包括Linux 系統的名稱和對應的版本號,以及該版本的代號。
2.2cat /etc/redhat-release
2.3cat /proc/cpuinfo |grep processor
查看cpu信息
2.4top法查看cpu信息
首先執行top命令;然后在top命令的顯示界面,按數字鍵1,即可查看到當前系統中的總cpu數。
2.5lscpu
2.6cat /proc/meminfo
2.6free -h|free -m|free -g
free-m以兆字節為單位顯示,free -g 以G字節為單位顯示
2.7uptime
查詢系統時間。有時候server上的時間跟我們生活上的時間并不一致,當通過history查詢到某個自己特別care的命令執行時間的時候,這時候如果想知道這個命令被執行的真正時間,那這個命令就派上用場了。
2.8查詢賬號相關信息
3.進程相關[感謝關注微信公眾號《芯片驗證日記》]
下面這些命令在工作日常也經常用到,也是基本中的基本。
3.1ps -ef |grep 進程關鍵字
查找指定進程java: ps -ef | grep java
查找指定進程vsim:
ps-ef |grep vsim
3.2bg和fg命令
linux下如果想一個任務或者程序在后臺執行可以使用&,實際上linux還提供了其他任務調度的命令。
bg :將一個在后臺暫停的命令,變成繼續執行;【background后景;背景;不顯眼的位置;底色】,列出已經停止或后臺的作業。
fg :將后臺中的命令調至前臺繼續運行,【foreground:前景,重要位置】,將最近的作業帶到前臺。
fg n:將作業n帶到前臺。
jobs:查看當前有多少在后臺運行的命令。
ctrl + z: 可以將一個正在前臺執行的命令放到后臺,并且暫停。
nohup 命令:不掛斷地運行命令。nohup就是不掛起的意思(nohang up)。
3.3殺掉僵尸進程
kill-9 進程id
xkill
通過xkill可以殺死圖形程序應用。用法如下圖所示,在terminal里面輸入xkill回車,會出現一個白/黑色的x, 然后用鼠標單擊想要殺死的應用,想殺哪個就用鼠標左鍵點擊哪個,還可以殺自己。
kill-9 -1
終止你擁有的全部進程,功能類似killall -u 用戶名
killall程序名
killallfirefox
注意:該命令可以使用-9 參數來強制殺死進程,killall -9 firefox
killall-u 用戶名
killall-u icer #功能類似kill -9 -1
pkill程序名
直接殺死所有進程,比如:
pkillfirefox
pkilljava
kill和pkill的區別:
kill 對應的是 PID,pkill 對應的是COMMAND
PID和COMMAND的關系,如下圖所示:
4.環境變量相關[感謝關注微信公眾號《芯片驗證日記》]
玩eda軟件的第一步就是要懂環境變量,基礎的不能再基礎的知識了。
4.1搜索環境變量的值
bash中搜索環境變量的值:env|grep 環境變量的名字
csh中搜索環境變量的值:setenv|grep 環境變量的名字
4.2增加或查看環境變量
bash中是export;
csh中是setenv
5.壓縮和解壓命令
5.1tar命令
把文件夾test壓縮為test.tar.gz
tar -zcvf /home/icer/test.tar.gz /temp/test #tar -zcvf 目標文件名.tar.gz 源文件名
把壓縮包解壓到特定目錄
tar -zxvf /home/icer/test.tar.gz-C /temp/ #C—change directory tar-xvf/home/icer/test.tar.gz-C/temp/
把壓縮包解壓到當前目錄
tar -zxvf /home/icer/data.tar.gz
把文件夾打包壓縮到當前目錄
tar -zcvf /home/icer/data.tar.gz /home/test/data
解壓.tar.xz格式
tar -xvJf data.tar.xz #其中J為大j,其他選項小寫
5.2zip/unzip命令
zip test.zip test
unzip test.zip
5.37za命令
7za -x filename.7z
6.查磁盤分區和文件夾占用空間
regression跑不下去了,磁盤空間是不是快爆了,分配給自己硬盤空間是不是已經滿了,這總得知道吧。
df命令
df -h ./
df -h ~
du命令
du -sh 目錄名
7.ls命令[感謝關注微信公眾號《芯片驗證日記》]
7.1ls
7.2ls -rtlah
7.3 ls -rtlha |grep"^d"#列出所有的目錄
7.4 ls -rtlh|grep"^-"#列出所有的文件
7.5 ls -rtla|grep"^d"|wc -l #顯示文件夾的數量
7.6 ls –ld .* #只顯示隱藏文件
8.cd命令[感謝關注微信公眾號《芯片驗證日記》]
cd ~:返回home目錄
cd -:返回前一目錄
cd../../ :返回上上級目錄
9.mkdir命令
mkdir-p
mkdir -p: 可以一次性創建多重目錄,p=parents
mkdir -p /home/icer/my_work/mydir
mkdir-m
mkdir-m=mkdir + chmod
mkdir -m 755 ~/auto_run.sh
10.touch
touch[文件名]
11.chmod
chmod 755 ~/my_work/foo.txt
12.chown 必須使用root權限操作,將文件~/eda/license.dat的所有者和所屬組均修改為icer
chown icer:icer ~/eda/license.dat
13.cp命令
cp [選項] [源] [目標]
cp -rf abc mnp cp -rf *.png *.txt *.sv /home/icer/ cp -rf /user/source/ /home/icer/
14.mv命令
mv <-f | -i> [文件1] [文件2]
mv <-f | -i> [目錄1] [目錄2]
mv <-f | -i> [文件列表] [目錄]
-f :如果目標文件已存在,不提示直接覆蓋已有文件。
-i :如果目標文件有同名,則先詢問是否覆蓋已有文件。
mv abc yyy mv /user/source/ /home/icer/des/ mv -i ./nic/*.sv ./flist
15.rm命令
rm<選項> [文件列表]
選項說明:
-r :recursion表示遞歸,將目錄及以下文件逐層刪除。
-f :force,
16.wc文件內容統計命令
wc <選項> 文件列表
統計指定文件中的字節數、字數、行數。
-c :character, 統計字節數
-l :line,統計行數
-w :word,統計字數
更多內容請參考,本公眾號另外一篇文章 查看整個項目的代碼行數
17.find命令 [感謝關注微信公眾號《芯片驗證日記》]
find[目錄列表] [匹配標準]
find . -name “*file*”
17.1按名稱搜索文件
普通用法
find . -name test.txt查找所有格式為 pdf 的書籍,使用正則表達式:
find ./icer/books -name "*.pdf"
默認情況下,find 命令會搜索常規文件,但最好進行指定(-type f)以使所有內容更清晰:
find ./icer/books -type f -name "*.pdf"
17.2查找不同類型的文件
通過指定 -type 選項來搜索其他類型的文件,例如搜索目錄:
find . -type d -name "icer*" #或者符號鏈接: find . -type l -name "icer*"
17.3 按指定的時間戳查找文件 搜索訪問access時間查過7天的
find . -type f -atime +7
查找修改modify時間正好是 5 天前的文件,請不要包含 +,因為它的意思是“大于”。
find . -type f -mtime 5
搜索更改change時間在 5~10 天前的文件:
find . -type f -ctime +5 -ctime -10
17.4 按大小查找文件
查找大小為 10 MB ~ 1 GB 的文件:
find . -type f -size +10M -size -1G
17.5 按權限查找文件
搜索所有具有 777 權限的文件,這意味著一個文件對其持有者、組和所有用戶具有所有的讀、寫和可執行權限。
find . -type f -perm 777
17.6 按用戶名查找文件
查找所有屬于icer的文件:
find -type f -user icer
17.7 在找到文件后執行命令(-exec)
find . -type f -atime +365 -exec rm -rf {} ;上述命令在 -exec 選項后是 rm -rf,其用于刪除文件。{} 是用于查找結果的占位符。 注意:占位符{} 非常重要,尤其是在您想刪除文件時。因為,如果您不使用它,該命令將對所有文件執行(而不是您剛剛通過find 命令找到的文件)。
做一個嘗試,在終端上執行以下兩個命令,并檢查它們的結果有何不同:
#一個使用占位符: find . -type f -atime +5 -exec ls {} ; #另一個不使用占位符: find . -type f -atime +5 -exec ls ;-exec 選項后面的命令必須以分號(;)結束。眾所周知,轉義字符用于去 除單個字符的特殊含義。在 Linux 中,反斜杠 用作轉義字符。所以我們將它用于分號字符。
17.8常規處理動作 [感謝關注微信公眾號《芯片驗證日記》]
17.8.1-print
默認的處理動作,顯示至屏幕
find / -name httpd.conf -print
17.8.2-ls
類似于對查找到的文件執行 "ls -l"命令
find / -type f -size +1G -ls
17.8.3-delete
刪除查找到的文件
find ~ -type d -empty -delete find ./ -type f -delete # 刪除大與100M,時間在7天前的文件 find /test -size +100M -mtime +7 -delete
17.8.4-fls /path/to/somefile
查找到的所有文件的長格式信息保存至指定文件中。
17.8.5-ok command {} ;
對查找到的每個文件執行由command指定的命令,對于每個文件執行命令之前,都會交互式要求用戶確認。
其中的大括號{}作為檢索到的文件的占位符,用于引用查找到的文件名稱自身,而分號(;)作為命令結束的標志, 需要轉義, 也可以用 + 號表示。-exec command {} ; 等同于 -exec command {} +
17.8.6-exec command {} ;
對查找到的每個文件執行由command指定的命令。其中的大括號{}作為檢索到的文件的占位符,用于引用查找到的文件名稱自身,而分號(;)作為命令結束的標志, 需要轉義, 也可以用 + 號表示。-exec command {} ; 等同于 -exec command {} +
幾個小例子:
find . -type d -maxdepth 1 find/var/mail/-size+50M-execrm{}; find.-name“*.sv”|xargsrm-rf find.-name“*.sv”-execrm-rf{}; find-typef|xargs-n3rm-rf find-typef|execrm-rf{};
17.8.7忽略大小寫
使用-iname參數選項
find . -iname "example*" -print
17.8.8否定參數
find 也可以用 ! 排除匹配到的模式,下面的find命令能夠匹配所有不以.txt結尾的文件。
find . ! -name "*.txt" -print #注意!和-name之間有空格
17.9find結合xargs
xargs(英文全拼:eXtended ARGumentS)是給命令傳遞參數的一個過濾器,也是組合多個命令的一個工具。xargs 可以將管道或標準輸入(stdin)數據轉換成命令行參數,也能夠從文件的輸出中讀取數據。xargs 作為后面命令的參數。
#將find查找的所有文件作為參數傳遞給grep進行過濾
find . -name “*file*” | xargs grep include # 查找大于20M的文件,并顯示具體大小 find./-typef-size+20M2>/dev/null|xargsdu-sh
# 查找大于60M的文件,并顯示詳細信息 find./-typef-size+60M2>/dev/null|xargsls-l
# 查找系統中最大的3個文件 find ./ -type f -exec du -sh {} + 2>/dev/null | sort -rh | head -n 3
18.grep命令 [感謝關注微信公眾號《芯片驗證日記》]
grep:查找文件內容。
grep -Rn “xx”,#一定要用R,不要用r,我是吃過虧的。18.1pgrep pgrep是一個根據名稱查找進程ID的命令,返回的是進程ID,若存在當個進程,則分為不同的行返回ID(默認實現)。
pgrep經常和其他命令配合使用,最常見的是kill:
19.tree命令
tree -L 2 文件件名稱
20.tee命令
tee的應用場景
向命令執行窗口輸出的同時,將內容輸出到文件。應用場景:將仿真過程中terminal中顯示的內容,輸出到特定的文件makerun|teexxx_tee.log
pingbaidu.com|teepb.log pingbaidu.com|tee-apb.log#追加 pingbaidu.com|teepb.logpb2.log#輸出到多個文件 catpb.log|tee|wc-l#將tee命令的輸出重定向為另一個命令的輸入流 #在vim打開的文件中輸入,:w!sudotee%#用tee命令提高寫入文件的權限等級 ping baidu.com |tee -i pb.log #讓tee命令忽略中斷事件
與自己對話如何呢,或者叫做復讀機?
tee命令直接跟文件的話,會等待輸入,并同步進行輸出到終端和文件的操作。
$tee test.log
hello
hello
world
world
$cat test.log
hello
world
21.split命令
split命令可以用于切割文件,將大文件切割成幾個小文件。
split-C 1M/10G xx.log
22.sed命令
sed主要用來直接處理文本文件。
sed -i “s/” a.sv
只打印那些發生替換的行
sed -n ‘s/uvm_hdl_read////&/p’ *.sv
直接修改用下面命令
sed -i ‘s/uvm_hdl_force///&/g’ *.sv
刪除所有空行
sed “s/^$/d” foo.sv
刪除所有只包含空格或者制表符的行
sed “s/^[ ] *$/d” foo.sv
刪除所有引號
sed “s/””//g” foo.sv
刪除所有//注釋的行
sed “s/////g” foo.sv
23.unix2dos命令
unix2dos是將Linux&Unix格式文件轉換為Windows格式文件的命令。dos2unix和unix2dos是互為孿生的一個命令,dos2unix是將Windows格式文件轉換為Unix、Linux格式的實用命令。Windows格式文件的換行符為 ,而Unix&Linux文件的換行符為 .dos2unix命令其實就是將文件中的 轉換為 。在windows下生成的license文件,放到linux中用時會用到該命令。
使用前需要先安裝:
yuminstall-ydos2unix yuminstall-yunix2dos
對單個文件操作:
unix2dos test.txt
對多個文件操作:
unix2dos test1.txt test2.txt test3.txt
對整個目錄中的文件做unix2dos操作:
find /path/to/dir -type f -exec unix2dos {} ;
如果要保持文件時間戳不變,加上-k參數
unix2dos -k test1.txt test2.txt
24.ln -s軟連接 [感謝關注微信公眾號《芯片驗證日記》]
創建軟連接
ln-s [源文件/目錄] [目標軟鏈接]
刪除軟連接
刪除軟鏈接和刪除文件/目錄操作一樣,使用rm命令。但是需要特別注意的是,如果只是刪除軟鏈接,不想誤刪除軟鏈接目錄真實文件數據,在rm目錄時路徑末尾一定不能帶"/"。如果帶了"/",會將鏈接到的路徑下的文件全部刪除。
25.lsof命令
lsof是linux下非常實用的系統級的監控、診斷工具。它是List Open Files的縮寫(lsopen file)。使用 lsof可以獲取任何被打開文件的各種信息,因為lsof 需要訪問核心內存和各種文件,所以必須以root用戶的身份運行它才能夠充分地發揮其功能。
26.ftp命令 [感謝關注微信公眾號《芯片驗證日記》]
格式:ftp[hostname| ip-address]
a)在linux命令行下輸入:
ftp192.168.1.1 #or ftp.company.com
b)服務器詢問你用戶名和密碼,分別輸入用戶名和相應密碼,待認證通過即可。
下載文件用get;下載多個文用mget;上傳文件用put;上傳多個文件用mput
27.sftp命令
sftp user@xxftp.company.com.cn,然后服務器詢問你的密碼,輸入密碼,待認證通過即可。
28.如何刪除一些奇怪的文件
a)進入奇怪文件所在的文件夾,ls-i 得到inode節點號,然后kill-9 inode節點號;
b)lsof.nfs* 可以找到掛住的進程,kill這個進程,這些隱藏文件就可以刪除了。
c)ps-ef |grep “.nfs*” 得到進程id,然后通過kill -9 進程id殺掉即可。
29./dev/null的含義和用途
/dev/是包含所有物理和虛擬設備的目錄。例如,/dev/sda 可能是主硬盤驅動器,/dev/sdb可能是正在使用的筆記本驅動器的文件。這就是在 Linux 中訪問設備的方式。除了這些物理設備(如硬盤驅動器)之外,Linux還具有虛擬設備。
虛擬設備是充當物理設備的設備,但實際上僅以軟件形式存在。應用程序可以從這些設備獲取數據,但該數據不是來自物理設備,而是來自/dev/null,/dev/null是一種特殊的虛擬設備,用于寫入而不是讀取。寫入/dev/null的任何內容都會從操作系統中消失。正是由于這個原因,/dev/null 被稱為 bitbucket。例如,將"Hello World"輸出重定向到/dev/null中。結果就沒有任何輸出。“Hello World”不存儲在系統上的任何文件中。它只是消失了。
/dev/null的使用:
在Linux中運行任何命令時,都會生成兩個輸出流,即標準輸出(stdout)和標準錯誤(stderr)。標準輸出是程序正常生成的任何輸出。標準錯誤包含命令生成的所有錯誤。stdout和stderr流可以通過它們的文件描述符(分別為 1 和 2)進行訪問。
/dev/null與stdout和stderr一起使用:如下圖所示,ping xrun.log是不會成功的,所以1>m.txt是有問題的,因為1代表標準輸出stdout;這里應該使用2>n.txt,因為2代表標準錯誤輸出,所以,m.txt是空的,n.txt里面存儲了標準錯誤輸出的結果。
如下圖所示,ping xrun.log 2>/dev/null是丟棄錯誤信息到/dev/null,系統沒有任何提示;ping xrun.log >/dev/null是丟棄正確信息到/dev/null,系統報錯。
概括來講,/dev/null 在Linux中是一個void,它會吸收任何輸入,并且不返回任何內容。大多數情況下,管理員使用它來轉儲無用的數據,在其中輸出,這樣它就不會占用系統內存和處理能力。甚至可以通過將無用的文件直接移動到/dev/null/ 來刪除它們。
審核編輯:湯梓紅
-
Linux
+關注
關注
87文章
11296瀏覽量
209358 -
命令
+關注
關注
5文章
683瀏覽量
22015 -
芯片驗證
+關注
關注
5文章
34瀏覽量
47224 -
Shell
+關注
關注
1文章
365瀏覽量
23358
原文標題:芯片驗證中linux用法小結
文章出處:【微信號:ExASIC,微信公眾號:ExASIC】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論