shell腳本日誌輸出
Ⅰ shell腳本中如何獲取錯誤輸出
不太明白你表達的意思,是無法看到錯誤信息還是想保存錯誤信息?
1、一般來講,shell命令都是有錯誤輸出的,它會列印在屏幕上,但實際上是標准錯誤輸出文件,如果我不想輸出到屏幕,而是寫到文件里,我們可以用管道符'>'重定向標准錯誤輸出,比如:
我cat一個不存在的文件,會有錯誤輸出,我可以把錯誤重定向到文件里
1
2
3
4
5
#cat /tmp/aa
cat: /tmp/aa: No such file or directory
#cat /tmp/aa 2>err.log
#cat err.log
cat: /tmp/aa: No such file or directory
2表示標准錯誤輸出。
另外,我甚至可以把錯誤輸出放到shell變數里:
1
2
3
#aa=$(cat /tmp/aa 2>&1)
#echo $aa
cat: /tmp/aa: No such file or directory
2>&1表示,我把錯誤輸出重定向到標准屏幕輸出1上,在賦值給變數aa
2、關於如何調試shell腳本
很簡單
1
#sh -vx xxxx.sh
上述命令會列印shell腳本的執行過程和結果,有助於排錯。當然,某些情況下,可能不會有輸出(如shell中有函數,可能就不會輸出函數里的過程)。
Ⅱ 如何將一shell腳本中的每一步命令執行結果輸出到指定日誌文件中
使用tee命令:
sh portal/main.sh |tee log.txt
獲取腳本父類路徑
cmddir="`dirname $0`"
Ⅲ 如何將一shell腳本中的每一步命令執行結果輸出到指定日誌文件中
$?獲取每一步執行的結果,輸出到日誌中就是正常的寫日誌動作就行
echo "" > /var/log/你的log
或者rsyslog啥的,我記得有個函數,你用這個函數也行。
Ⅳ shell腳本怎麼生成運行日誌
自己寫的腳本調用的日誌列印函數,供參考
在腳本開頭的工作
定義日誌文件LOGFILE
定義日誌序列號文件_LOGSEQ
定義日誌函數
log()
{
#檢查是否存在日誌文件,如果存在,則檢查文件是否過大(20M)
#過大時,切換文件,並將目前的日誌序列號保存在_LOGSEQ中。
if [ -f $LOGFILE ];then
LogFileLen=`ls -l ${LOGFILE} | awk '{print $5}'`
if [ $LogFileLen -gt 20971520 ]; then
if [ -f ${_LOGSEQ} ] ; then
_OrgSeq="`cat ${_LOGSEQ}`"
if [ $_OrgSeq -gt 98 ];then
LogFileSeq=0
else
LogFileSeq=`expr ${_OrgSeq} + 1`
fi
else
LogFileSeq=0
fi
echo "${LogFileSeq}" > ${_LOGSEQ}
mv $LOGFILE ${LOGFILE}.${LogFileSeq}
fi
fi
_LogInfo=$1
echo `date +20'%y-%m-%d %H:%M:%S'`" ${_LogInfo} " >> ${LOGFILE} 2>&1
}
需要打日誌時調用log函數即可
Ⅳ 求助:如何在shell腳本中添加寫日誌的功能
如何編寫一個shell腳本本文結合大量實例闡述如何編寫一個shell腳本。為什麼要進行shell編程在linux系統中,雖然有各種各樣的圖形化介面工具,但是sell仍然是一個非常靈活的工具。Shell不僅僅是命令的收集,而且是一門非常棒的編程語言。您可以通過使用shell使大量的任務自動化,shell特別擅長系統管理任務,尤其適合那些易用性、可維護性和便攜性比效率更重要的任務。下面,讓我們一起來看看shell是如何工作的:建立一個腳本Linux中有好多中不同的shell,但是通常我們使用bash(bourneagainshell)進行shell編程,因為bash是免費的並且很容易使用。所以在本文中筆者所提供的腳本都是使用bash(但是在大多數情況下,這些腳本同樣可以在bash的大姐,bourneshell中運行)。如同其他語言一樣,通過我們使用任意一種文字編輯器,比如nedit、kedit、emacs、vi等來編寫我們的shell程序。程序必須以下面的行開始(必須方在文件的第一行):#!/bin/sh符號#!用來告訴系統它後面的參數是用來執行該文件的程序。在這個例子中我們使用/bin/sh來執行程序。當編輯好腳本時,如果要執行該腳本,還必須使其可執行。要使腳本可執行:chmod+xfilename然後,您可以通過輸入:./filename來執行您的腳本。注釋在進行shell編程時,以#開頭的句子表示注釋,直到這一行的結束。我們真誠地建議您在程序中使用注釋。如果您使用了注釋,那麼即使相當長的時間內沒有使用該腳本,您也能在很短的時間內明白該腳本的作用及工作原理。變數在其他編程語言中您必須使用變數。在shell編程中,所有的變數都由字元串組成,並且您不需要對變數進行聲明。要賦值給一個變數,您可以這樣寫:變數名=值取出變數值可以加一個美元符號($)在變數前面:#!/bin/sh#對變數賦值:a="helloworld"#現在列印變數a的內容:echo"Ais:"echo$a在您的編輯器中輸入以上內容,然後將其保存為一個文件first。之後執行chmod+xfirst使其可執行,最後輸入./first執行該腳本。這個腳本將會輸出:Ais:helloworld有時候變數名很容易與其他文字混淆,比如:num=2echo"thisisthe$numnd"這並不會列印出"thisisthe2nd",而僅僅列印"thisisthe",因為shell會去搜索變數numnd的值,但是這個變數時沒有值的。可以使用花括弧來告訴shell我們要列印的是num變數:num=2echo"thisisthe${num}nd"這將列印:thisisthe2nd有許多變數是系統自動設定的,這將在後面使用這些變數時進行討論。如果您需要處理數學表達式,那麼您需要使用諸如expr等程序(見下面)。除了一般的僅在程序內有效的shell變數以外,還有環境變數。由export關鍵字處理過的變數叫做環境變數。我們不對環境變數進行討論,因為通常情況下僅僅在登錄腳本中使用環境變數。Shell命令和流程式控制制在shell腳本中可以使用三類命令:1)Unix命令:雖然在shell腳本中可以使用任意的unix命令,但是還是由一些相對更常用的命令。這些命令通常是用來進行文件和文字操作的。常用命令語法及功能echo"sometext":將文字內容列印在屏幕上ls:文件列表wc–lfilewc-wfilewc-cfile:計算文件行數計算文件中的單詞數計算文件中的字元數cpsourcefiledestfile:文件拷貝mvoldnamenewname:重命名文件或移動文件rmfile:刪除文件grep'pattern'file:在文件內搜索字元串比如:grep'searchstring'file.txtcut-bcolnumfile:指定欲顯示的文件內容範圍,並將它們輸出到標准輸出設備比如:輸出每行第5個到第9個字元cut-b5-9file.txt千萬不要和cat命令混淆,這是兩個完全不同的命令catfile.txt:輸出文件內容到標准輸出設備(屏幕)上filesomefile:得到文件類型readvar:提示用戶輸入,並將輸入賦值給變數sortfile.txt:對file.txt文件中的行進行排序uniq:刪除文本文件中出現的行列比如:sortfile.txt|uniqexpr:進行數學運算Example:add2and3expr2"+"3find:搜索文件比如:根據文件名搜索find.-namefilename-printtee:將數據輸出到標准輸出設備(屏幕)和文件比如:somecommand|teeoutfilebasenamefile:返回不包含路徑的文件名比如:basename/bin/tux將返回tuxdirnamefile:返迴文件所在路徑比如:dirname/bin/tux將返回/binheadfile:列印文本文件開頭幾行tailfile:列印文本文件末尾幾行sed:Sed是一個基本的查找替換程序。可以從標准輸入(比如命令管道)讀入文本,並將結果輸出到標准輸出(屏幕)。該命令採用正則表達式(見參考)進行搜索。不要和shell中的通配符相混淆。比如:將linuxfocus替換為LinuxFocus:cattext.file|sed's/linuxfocus/LinuxFocus/'>newtext.fileawk:awk用來從文本文件中提取欄位。預設地,欄位分割符是空格,可以使用-F指定其他分割符。catfile.txt|awk-F,'{print$1","$3}'這里我們使用,作為欄位分割符,同時列印第一個和第三個欄位。如果該文件內容如下:AdamBor,34,IndiaKerryMiller,22,USA命令輸出結果為:AdamBor,IndiaKerryMiller,USA2)概念:管道,重定向和backtick這些不是系統命令,但是他們真的很重要。管道(|)將一個命令的輸出作為另外一個命令的輸入。grep"hello"file.txt|wc-l在file.txt中搜索包含有」hello」的行並計算其行數。在這里grep命令的輸出作為wc命令的輸入。當然您可以使用多個命令。重定向:將命令的結果輸出到文件,而不是標准輸出(屏幕)。>寫入文件並覆蓋舊文件>>加到文件的尾部,保留舊文件內容。反短斜線使用反短斜線可以將一個命令的輸出作為另外一個命令的一個命令行參數。命令:find.-mtime-1-typef-print用來查找過去24小時(-mtime–2則表示過去48小時)內修改過的文件。如果您想將所有查找到的文件打一個包,則可以使用以下腳本:#!/bin/sh#Theticksarebackticks(`)notnormalquotes('):tar-zcvflastmod.tar.gz`find.-mtime-1-typef-print`3)流程式控制制"if"表達式如果條件為真則執行then後面的部分:if.;then.elif.;then.else.fi大多數情況下,可以使用測試命令來對條件進行測試。比如可以比較字元串、判斷文件是否存在及是否可讀等等…通常用"[]"來表示條件測試。注意這里的空格很重要。要確保方括弧的空格。[-f"somefile"]:判斷是否是一個文件[-x"/bin/ls"]:判斷/bin/ls是否存在並有可執行許可權[-n"$var"]:判斷$var變數是否有值["$a"="$b"]:判斷$a和$b是否相等執行mantest可以查看所有測試表達式可以比較和判斷的類型。直接執行以下腳本:#!/bin/shif["$SHELL"="/bin/bash"];thenecho"yourloginshellisthebash(bourneagainshell)"elseecho"yourloginshellisnotbashbut$SHELL"fi變數$SHELL包含了登錄shell的名稱,我們和/bin/bash進行了比較。快捷操作符熟悉C語言的朋友可能會很喜歡下面的表達式:[-f"/etc/shadow"]&&echo""這里&&就是一個快捷操作符,如果左邊的表達式為真則執行右邊的語句。您也可以認為是邏輯運算中的與操作。上例中表示如果/etc/shadow文件存在則列印」」。同樣或操作(||)在shell編程中也是可用的。這里有個例子:#!/bin/shmailfolder=/var/spool/mail/james[-r"$mailfolder"]''{echo"Cannotread$mailfolder";exit1;}echo"$mailfolderhasmailfrom:"grep"^From"$mailfolder該腳本首先判斷mailfolder是否可讀。如果可讀則列印該文件中的"From"一行。如果不可讀則或操作生效,列印錯誤信息後腳本退出。這里有個問題,那就是我們必須有兩個命令:-列印錯誤信息-退出程序我們使用花括弧以匿名函數的形式將兩個命令放到一起作為一個命令使用。一般函數將在下文提及。不用與和或操作符,我們也可以用if表達式作任何事情,但是使用與或操作符會更便利很多。case表達式可以用來匹配一個給定的字元串,而不是數字。casein)dosomethinghere;;esac讓我們看一個例子。file命令可以辨別出一個給定文件的文件類型,比如:filelf.gz這將返回:lf.gz:gzipcompresseddata,deflated,originalfilename,lastmodified:MonAug2723:09:182001,os:Unix我們利用這一點寫了一個叫做smartzip的腳本,該腳本可以自動解壓bzip2,gzip和zip類型的壓縮文件:#!/bin/shftype=`file"$1"`case"$ftype"in"$1:Ziparchive"*)unzip"$1";;"$1:gzipcompressed"*)gunzip"$1";;"$1:bzip2compressed"*)bunzip2"$1";;*)error"File$";;esac您可能注意到我們在這里使用了一個特殊的變數$1。該變數包含了傳遞給該程序的第一個參數值。也就是說,當我們運行:smartziparticles.zip$1就是字元串articles.zipselect表達式是一種bash的擴展應用,尤其擅長於互動式使用。用戶可以從一組不同的值中進行選擇。selectvarin;dobreakdone.now$varcanbeused.下面是一個例子:#!/bin/shecho"WhatisyourfavouriteOS?"selectvarin"Linux""GnuHurd""FreeBSD""Other";dobreakdoneecho"Youhaveselected$var"下面是該腳本運行的結果:WhatisyourfavouriteOS?1)Linux2)GnuHurd3)FreeBSD4)Other#?1YouhaveselectedLinux您也可以在shell中使用如下的loop表達式:while;do.donewhile-loop將運行直到表達式測試為真。.關鍵字"break"用來跳出循環。而關鍵字」continue」用來不執行餘下的部分而直接跳到下一個循環。for-loop表達式查看一個字元串列表(字元串用空格分隔)然後將其賦給一個變數:forvarin.;do.done在下面的例子中,將分別列印ABC到屏幕上:#!/bin/shforvarinABC;doecho"varis$var"done下面是一個更為有用的腳本showrpm,其功能是列印一些RPM包的統計信息:#!/bin/sh##USAGE:showrpmrpmfile1rpmfile2#EXAMPLE:showrpm/cdrom/RedHat/RPMS/*.rpmforrpmpackagein$*;doif[-r"$rpmpackage"];thenecho"===============$rpmpackage=============="rpm-qi-p$rpmpackageelseecho"ERROR:cannotreadfile$rpmpackage"fidone這里出現了第二個特殊的變數$*,該變數包含了所有輸入的命令行參數值。如果您運行showrpmopenssh.rpmw3m.rpmwebgrep.rpm此時$*包含了3個字元串,即openssh.rpm,w3m.rpmandwebgrep.rpm.引號在向程序傳遞任何參數之前,程序會擴展通配符和變數。這里所謂擴展的意思是程序會把通配符(比如*)替換成合適的文件名,它變數替換成變數值。為了防止程序作這種替換,您可以使用引號:讓我們來看一個例子,假設在當前目錄下有一些文件,兩個jpg文件,mail.jpg和tux.jpg。#!/bin/shecho*.jpg這將列印出"mail.jpgtux.jpg"的結果。引號(單引號和雙引號)將防止這種通配符擴展:#!/bin/shecho"*.jpg"echo'*.jpg'這將列印"*.jpg"兩次。單引號更嚴格一些。它可以防止任何變數擴展。雙引號可以防止通配符擴展但允許變數擴展。#!/bin/shecho$SHELLecho"$SHELL"echo'$SHELL'運行結果為:/bin/bash/bin/bash$SHELL最後,還有一種防止這種擴展的方法,那就是使用轉義字元——反斜桿:echo*.jpgecho$SHELL這將輸出:*.jpg$SHELLHeredocuments當要將幾行文字傳遞給一個命令時,heredocuments(譯者註:目前還沒有見到過對該詞適合的翻譯)一種不錯的方法。對每個腳本寫一段幫助性的文字是很有用的,此時如果我們四有那個heredocuments就不必用echo函數一行行輸出。一個"Heredocument"以shiftby2--)shift;break;;#endofoptions-*)echo"error:nosuchoption$1.-hforhelp";exit1;;*)break;;esacdoneecho"opt_fis$opt_f"echo"opt_lis$opt_l"echo"firstargis$1"echo"2ndargis$2"您可以這樣運行該腳本:cmdparser-lhello-f---somefile1somefile2返回的結果是:opt_fis1opt_lishellofirstargis-somefile12ndargissomefile2這個腳本是如何工作的呢?腳本首先在所有輸入命令行參數中進行循環,將輸入參數與case表達式進行比較,如果匹配則設置一個變數並且移除該參數。根據unix系統的慣例,首先輸入的應該是包含減號的參數。實例一般編程步驟現在我們來討論編寫一個腳本的一般步驟。任何優秀的腳本都應該具有幫助和輸入參數。並且寫一個偽腳本(framework.sh),該腳本包含了大多數腳本都需要的框架結構,是一個非常不錯的主意。這時候,在寫一個新的腳本時我們只需要執行一下命令:cpframework.shmyscript然後再插入自己的函數。讓我們再看兩個例子:二進制到十進制的轉換腳本b2d將二進制數(比如1101)轉換為相應的十進制數。這也是一個用expr命令進行數學運算的例子:#!/bin/sh#vim:setsw=4ts=4et:help(){cat<
Ⅵ shell鑴氭湰鍚庡彴榪愯
浣跨敤nohup錛屽叾涓璼ample.sh涓烘墍鎵ц岀殑鑴氭湰錛宱ut.log涓烘棩蹇楄緭鍑烘枃浠躲
nohup sh sample.sh>out.log &
浣跨敤sh錛屽叾涓璼ample.sh涓烘墍鎵ц岀殑鑴氭湰錛宱ut.log涓烘棩蹇楄緭鍑烘枃浠躲
sh sample.sh>&out.log &
& 鏀懼湪鍚鍔ㄥ弬鏁板悗闈㈣〃紺鴻劇疆姝よ繘紼嬩負鍚庡彴榪涚▼