A. 如何編寫一個shell腳本
如何編寫一個shell腳本
本文結合大量實例闡述如何編寫一個shell腳本。
為什麼要進行shell編程
在linux系統中,雖然有各種各樣的圖形化介面工具,但是sell仍然是一個非常靈活的工具。Shell不僅僅是命令的收集,而且是一門非常棒的編程語言。您可以通過使用shell使大量的任務自動化,shell特別擅長系統管理任務,尤其適合那些易用性、可維護性和便攜性比效率更重要的任務。
下面,讓我們一起來看看shell是如何工作的:
建立一個腳本
Linux中有好多中不同的shell,但是通常我們使用bash (bourne again shell) 進行shell編程,因為bash是免費的並且很容易使用。所以在本文中筆者所提供的腳本都是使用bash(但是在大多數情況下,這些腳本同樣可以在bash的大姐,bourne shell中運行)。
如同其他語言一樣,通過我們使用任意一種文字編輯器,比如nedit、kedit、emacs、vi
等來編寫我們的shell程序。
程序必須以下面的行開始(必須方在文件的第一行):
#!/bin/sh
符號#!用來告訴系統它後面的參數是用來執行該文件的程序。在這個例子中我們使用/bin/sh來執行程序。
當編輯好腳本時,如果要執行該腳本,還必須使其可執行。
要使腳本可執行:
chmod +x filename
然後,您可以通過輸入: ./filename 來執行您的腳本。
注釋
在進行shell編程時,以#開頭的句子表示注釋,直到這一行的結束。我們真誠地建議您在程序中使用注釋。如果您使用了注釋,那麼即使相當長的時間內沒有使用該腳本,您也能在很短的時間內明白該腳本的作用及工作原理。
變數
在其他編程語言中您必須使用變數。在shell編程中,所有的變數都由字元串組成,並且您不需要對變數進行聲明。要賦值給一個變數,您可以這樣寫:
變數名=值
取出變數值可以加一個美元符號($)在變數前面:
#!/bin/sh
#對變數賦值:
a="hello world"
# 現在列印變數a的內容:
echo "A is:"
echo $a
在您的編輯器中輸入以上內容,然後將其保存為一個文件first。之後執行chmod +x first
使其可執行,最後輸入./first執行該腳本。
這個腳本將會輸出:
A is:
hello world
有時候變數名很容易與其他文字混淆,比如:
num=2
echo "this is the $numnd"
這並不會列印出"this is the 2nd",而僅僅列印"this is the ",因為shell會去搜索變數numnd的值,但是這個變數時沒有值的。可以使用花括弧來告訴shell我們要列印的是num變數:
num=2
echo "this is the ${num}nd"
這將列印: this is the 2nd
有許多變數是系統自動設定的,這將在後面使用這些變數時進行討論。
如果您需要處理數學表達式,那麼您需要使用諸如expr等程序(見下面)。
除了一般的僅在程序內有效的shell變數以外,還有環境變數。由export關鍵字處理過的變數叫做環境變數。我們不對環境變數進行討論,因為通常情況下僅僅在登錄腳本中使用環境變數。
Shell命令和流程式控制制
在shell腳本中可以使用三類命令:
1)Unix 命令:
雖然在shell腳本中可以使用任意的unix命令,但是還是由一些相對更常用的命令。這些命令通常是用來進行文件和文字操作的。
常用命令語法及功能
echo "some text": 將文字內容列印在屏幕上
ls: 文件列表
wc –l filewc -w filewc -c file: 計算文件行數計算文件中的單詞數計算文件中的字元數
cp sourcefile destfile: 文件拷貝
mv oldname newname : 重命名文件或移動文件
rm file: 刪除文件
grep 'pattern' file: 在文件內搜索字元串比如:grep 'searchstring' file.txt
cut -b colnum file: 指定欲顯示的文件內容範圍,並將它們輸出到標准輸出設備比如:輸出每行第5個到第9個字元cut -b5-9 file.txt千萬不要和cat命令混淆,這是兩個完全不同的命令
cat file.txt: 輸出文件內容到標准輸出設備(屏幕)上
file somefile: 得到文件類型
read var: 提示用戶輸入,並將輸入賦值給變數
sort file.txt: 對file.txt文件中的行進行排序
uniq: 刪除文本文件中出現的行列比如: sort file.txt | uniq
expr: 進行數學運算Example: add 2 and 3expr 2 "+" 3
find: 搜索文件比如:根據文件名搜索find . -name filename -print
tee: 將數據輸出到標准輸出設備(屏幕) 和文件比如:somecommand | tee outfile
basename file: 返回不包含路徑的文件名比如: basename /bin/tux將返回 tux
dirname file: 返迴文件所在路徑比如:dirname /bin/tux將返回 /bin
head file: 列印文本文件開頭幾行
tail file : 列印文本文件末尾幾行
sed: Sed是一個基本的查找替換程序。可以從標准輸入(比如命令管道)讀入文本,並將結果輸出到標准輸出(屏幕)。該命令採用正則表達式(見參考)進行搜索。不要和shell中的通配符相混淆。比如:將linuxfocus 替換為 LinuxFocus :cat text.file | sed 's/linuxfocus/LinuxFocus/' > newtext.file
awk: awk 用來從文本文件中提取欄位。預設地,欄位分割符是空格,可以使用-F指定其他分割符。cat file.txt | awk -F, '{print $1 "," $3 }'這里我們使用,作為欄位分割符,同時列印第一個和第三個欄位。如果該文件內容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令輸出結果為:Adam Bor, IndiaKerry Miller, USA
2) 概念: 管道, 重定向和 backtick
這些不是系統命令,但是他們真的很重要。
管道 (|) 將一個命令的輸出作為另外一個命令的輸入。
grep "hello" file.txt | wc -l
在file.txt中搜索包含有地hello地的行並計算其行數。
在這里grep命令的輸出作為wc命令的輸入。當然您可以使用多個命令。
重定向:將命令的結果輸出到文件,而不是標准輸出(屏幕)。
> 寫入文件並覆蓋舊文件
>> 加到文件的尾部,保留舊文件內容。
反短斜線
使用反短斜線可以將一個命令的輸出作為另外一個命令的一個命令行參數。
命令:
find . -mtime -1 -type f -print
用來查找過去24小時(-mtime –2則表示過去48小時)內修改過的文件。如果您想將所有查找到的文件打一個包,則可以使用以下腳本:
#!/bin/sh
# The ticks are backticks (`) not normal quotes ('):
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
3) 流程式控制制
"if" 表達式 如果條件為真則執行then後面的部分:
if ....; then
....
elif ....; then
....
else
....
fi
大多數情況下,可以使用測試命令來對條件進行測試。比如可以比較字元串、判斷文件是否存在及是否可讀等等…
通常用" [ ] "來表示條件測試。注意這里的空格很重要。要確保方括弧的空格。
[ -f "somefile" ] :判斷是否是一個文件
[ -x "/bin/ls" ] :判斷/bin/ls是否存在並有可執行許可權
[ -n "$var" ] :判斷$var變數是否有值
[ "$a" = "$b" ] :判斷$a和$b是否相等
執行man test可以查看所有測試表達式可以比較和判斷的類型。
直接執行以下腳本:
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but $SHELL"
fi
變數$SHELL包含了登錄shell的名稱,我們和/bin/bash進行了比較。
快捷操作符
熟悉C語言的朋友可能會很喜歡下面的表達式:
[ -f "/etc/shadow" ] && echo "This computer uses shadow passwors"
這里 && 就是一個快捷操作符,如果左邊的表達式為真則執行右邊的語句。您也可以認為是邏輯運算中的與操作。上例中表示如果/etc/shadow文件存在則列印地 This computer uses shadow passwors地。同樣或操作(||)在shell編程中也是可用的。這里有個例子:
#!/bin/sh
mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ]' '{ echo "Can not read $mailfolder" ; exit 1; }
echo "$mailfolder has mail from:"
grep "^From " $mailfolder
該腳本首先判斷mailfolder是否可讀。如果可讀則列印該文件中的"From" 一行。如果不可讀則或操作生效,列印錯誤信息後腳本退出。這里有個問題,那就是我們必須有兩個命令:
-列印錯誤信息
-退出程序
我們使用花括弧以匿名函數的形式將兩個命令放到一起作為一個命令使用。一般函數將在下文提及。
不用與和或操作符,我們也可以用if表達式作任何事情,但是使用與或操作符會更便利很多。
case表達式可以用來匹配一個給定的字元串,而不是數字。
case ... in
...) do something here ;;
esac
讓我們看一個例子。 file命令可以辨別出一個給定文件的文件類型,比如:
file lf.gz
這將返回:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我們利用這一點寫了一個叫做smartzip的腳本,該腳本可以自動解壓bzip2, gzip 和zip 類型的壓縮文件:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*) error "File $1 can not be uncompressed with smartzip";;
esac
您可能注意到我們在這里使用了一個特殊的變數$1。該變數包含了傳遞給該程序的第一個參數值。也就是說,當我們運行:
smartzip articles.zip
$1 就是字元串 articles.zip
select 表達式是一種bash的擴展應用,尤其擅長於互動式使用。用戶可以從一組不同的值中進行選擇。
select var in ... ; do
break
done
.... now $var can be used ....
下面是一個例子:
#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break
done
echo "You have selected $var"
下面是該腳本運行的結果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux
您也可以在shell中使用如下的loop表達式:
while ...; do
....
done
while-loop 將運行直到表達式測試為真。will run while the expression that we test for is true. 關鍵字"break" 用來跳出循環。而關鍵字地continue地用來不執行餘下的部分而直接跳到下一個循環。
for-loop表達式查看一個字元串列表 (字元串用空格分隔) 然後將其賦給一個變數:
for var in ....; do
....
done
在下面的例子中,將分別列印ABC到屏幕上:
#!/bin/sh
for var in A B C ; do
echo "var is $var"
done
下面是一個更為有用的腳本showrpm,其功能是列印一些RPM包的統計信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
這里出現了第二個特殊的變數$*,該變數包含了所有輸入的命令行參數值。如果您運行showrpm openssh.rpm w3m.rpm webgrep.rpm
此時 $* 包含了 3 個字元串,即openssh.rpm, w3m.rpm and webgrep.rpm.
引號
在向程序傳遞任何參數之前,程序會擴展通配符和變數。這里所謂擴展的意思是程序會把通配符(比如*)替換成合適的文件名,它變數替換成變數值。為了防止程序作這種替換,您可以使用引號:讓我們來看一個例子,假設在當前目錄下有一些文件,兩個jpg文件, mail.jpg 和tux.jpg。
#!/bin/sh
echo *.jpg
這將列印出"mail.jpg tux.jpg"的結果。
引號 (單引號和雙引號) 將防止這種通配符擴展:
#!/bin/sh
echo "*.jpg"
echo '*.jpg'
這將列印"*.jpg" 兩次。
單引號更嚴格一些。它可以防止任何變數擴展。雙引號可以防止通配符擴展但允許變數擴展。
#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'
運行結果為:
/bin/bash
/bin/bash
$SHELL
最後,還有一種防止這種擴展的方法,那就是使用轉義字元——反斜桿:
echo *.jpg
echo $SHELL
這將輸出:
*.jpg
$SHELL
Here documents
當要將幾行文字傳遞給一個命令時,here documents(譯者註:目前還沒有見到過對該詞適合的翻譯)一種不錯的方法。對每個腳本寫一段幫助性的文字是很有用的,此時如果我們四有那個here documents就不必用echo函數一行行輸出。 一個 "Here document" 以 << 開頭,後面接上一個字元串,這個字元串還必須出現在here document的末尾。下面是一個例子,在該例子中,我們對多個文件進行重命名,並且使用here documents列印幫助:
#!/bin/sh
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat <<HELP
ren -- renames a number of files using sed regular expressions
USAGE: ren 'regexp' 'replacement' files...
EXAMPLE: rename all *.HTM files in *.html:
ren 'HTM$' 'html' *.HTM
HELP
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $* contains now all the files:
for file in $*; do
if [ -f "$file" ] ; then
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; then
echo "ERROR: $newfile exists already"
else
echo "renaming $file to $newfile ..."
mv "$file" "$newfile"
fi
fi
done
這是一個復雜一些的例子。讓我們詳細討論一下。第一個if表達式判斷輸入命令行參數是否小於3個 (特殊變數$# 表示包含參數的個數) 。如果輸入參數小於3個,則將幫助文字傳遞給cat命令,然後由cat命令將其列印在屏幕上。列印幫助文字後程序退出。 如果輸入參數等於或大於3個,我們就將第一個參數賦值給變數OLD,第二個參數賦值給變數NEW。下一步,我們使用shift命令將第一個和第二個參數從參數列表中刪除,這樣原來的第三個參數就成為參數列表$*的第一個參數。然後我們開始循環,命令行參數列表被一個接一個地被賦值給變數$file。接著我們判斷該文件是否存在,如果存在則通過sed命令搜索和替換來產生新的文件名。然後將反短斜線內命令結果賦值給newfile。這樣我們就達到了我們的目的:得到了舊文件名和新文件名。然後使用mv命令進行重命名。
函數
如果您寫了一些稍微復雜一些的程序,您就會發現在程序中可能在幾個地方使用了相同的代碼,並且您也會發現,如果我們使用了函數,會方便很多。一個函數是這個樣子的:
functionname()
{
# inside the body $1 is the first argument given to the function
# $2 the second ...
body
}
您需要在每個程序的開始對函數進行聲明。
下面是一個叫做xtitlebar的腳本,使用這個腳本您可以改變終端窗口的名稱。這里使用了一個叫做help的函數。正如您可以看到的那樣,這個定義的函數被使用了兩次。
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <<HELP
xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] "string_for_titelbar"
OPTIONS: -h help text
EXAMPLE: xtitlebar "cvs"
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
[ -z "$1" ] && help
[ "$1" = "-h" ] && help
# send the escape sequence to change the xterm titelbar:
echo -e "33]0;$107"
#
在腳本中提供幫助是一種很好的編程習慣,這樣方便其他用戶(和您)使用和理解腳本。
命令行參數
我們已經見過$* 和 $1, $2 ... $9 等特殊變數,這些特殊變數包含了用戶從命令行輸入的參數。迄今為止,我們僅僅了解了一些簡單的命令行語法(比如一些強制性的參數和查看幫助的-h選項)。但是在編寫更復雜的程序時,您可能會發現您需要更多的自定義的選項。通常的慣例是在所有可選的參數之前加一個減號,後面再加上參數值 (比如文件名)。
有好多方法可以實現對輸入參數的分析,但是下面的使用case表達式的例子無遺是一個不錯的方法。
#!/bin/sh
help()
{
cat <<HELP
This is a generic command line parser demo.
USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2
HELP
exit 0
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
-f) opt_f=1;shift 1;; # variable opt_f is set
-l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2
--) shift;break;; # end of options
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
echo "opt_f is $opt_f"
echo "opt_l is $opt_l"
echo "first arg is $1"
echo "2nd arg is $2"
您可以這樣運行該腳本:
cmdparser -l hello -f -- -somefile1 somefile2
返回的結果是:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2
這個腳本是如何工作的呢看腳本首先在所有輸入命令行參數中進行循環,將輸入參數與case表達式進行比較,如果匹配則設置一個變數並且移除該參數。根據unix系統的慣例,首先輸入的應該是包含減號的參數。
實例
一般編程步驟
現在我們來討論編寫一個腳本的一般步驟。任何優秀的腳本都應該具有幫助和輸入參數。並且寫一個偽腳本(framework.sh),該腳本包含了大多數腳本都需要的框架結構,是一個非常不錯的主意。這時候,在寫一個新的腳本時我們只需要執行一下命令:
cp framework.sh myscript
然後再插入自己的函數。
讓我們再看兩個例子:
二進制到十進制的轉換
腳本 b2d 將二進制數 (比如 1101) 轉換為相應的十進制數。這也是一個用expr命令進行數學運算的例子:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <<HELP
b2h -- convert binary to decimal
USAGE: b2h [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2h 111010
will return 58
HELP
exit 0
}
error()
{
# print an error and exit
echo "$1"
exit 1
}
lastchar()
{
# return the last character of a string in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g' `
# now cut out the last char
rval=`echo -n "$1" | cut -b $numofchar`
}
chop()
{
# remove the last character in string and return it in $rval
if [ -z "$1" ]; then
# empty string
rval=""
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=`echo -n "$1" | wc -c | sed 's/ //g' `
if [ "$numofchar" = "1" ]; then
# only one char in string
rval=""
return
fi
numofcharminus1=`expr $numofchar "-" 1`
# now cut all but the last char:
rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
--) shift;break;; # end of options
-*) error "error: no such option $1. -h for help";;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z "$1" ] && help
binnum="$1"
binnumorig="$1"
while [ -n "$binnum" ]; do
lastchar "$binnum"
if [ "$rval" = "1" ]; then
sum=`expr "$weight" "+" "$sum"`
fi
# remove the last position in $binnum
chop "$binnum"
binnum="$rval"
weight=`expr "$weight" "*" 2`
done
echo "binary $binnumorig is decimal $sum"
#
該腳本使用的演算法是利用十進制和二進制數權值 (1,2,4,8,16,..),比如二進制"10"可以這樣轉換成十進制:
0 * 1 + 1 * 2 = 2
為了得到單個的二進制數我們是用了lastchar 函數。該函數使用wc –c計算字元個數,然後使用cut命令取出末尾一個字元。Chop函數的功能則是移除最後一個字元。
文件循環程序
或許您是想將所有發出的郵件保存到一個文件中的人們中的一員,但是在過了幾個月以後,這個文件可能會變得很大以至於使對該文件的訪問速度變慢。下面的腳本rotatefile 可以解決這個問題。這個腳本可以重命名郵件保存文件(假設為outmail)為outmail.1,而對於outmail.1就變成了outmail.2 等等等等...
#!/bin/sh
# vim: set sw=4 ts=4 et:
ver="0.1"
help()
{
cat <<HELP
rotatefile -- rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
}
error()
{
echo "$1"
exit 1
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;;
--) break;;
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
# input check:
if [ -z "$1" ] ; then
error "ERROR: you must specify a file, use -h for help"
fi
filen="$1"
# rename any .1 , .2 etc file:
for n in 9 8 7 6 5 4 3 2 1; do
if [ -f "$filen.$n" ]; then
p=`expr $n + 1`
echo "mv $filen.$n $filen.$p"
mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f "$filen" ]; then
echo "mv $filen $filen.1"
mv $filen $filen.1
fi
echo touch $filen
touch $filen
這個腳本是如何工作的呢看在檢測用戶提供了一個文件名以後,我們進行一個9到1的循環。文件9被命名為10,文件8重命名為9等等。循環完成之後,我們將原始文件命名為文件1同時建立一個與原始文件同名的空文件。
調試
最簡單的調試命令當然是使用echo命令。您可以使用echo在任何懷疑出錯的地方列印任何變數值。這也是絕大多數的shell程序員要花費80%的時間來調試程序的原因。Shell程序的好處在於不需要重新編譯,插入一個echo命令也不需要多少時間。
shell也有一個真實的調試模式。如果在腳本"strangescript" 中有錯誤,您可以這樣來進行調試:
sh -x strangescript
這將執行該腳本並顯示所有變數的值。
shell還有一個不需要執行腳本只是檢查語法的模式。可以這樣使用:
sh -n your_script
這將返回所有語法錯誤。
B. 學寫腳本開始要學什麼
學寫腳本開始要學腳本語言、基礎的程序編程和計算機原理。腳本語言是比較多的,一般的腳本語言的執行只同具體的解釋執行器有關,所以只要系統上有相應語言的解釋程序就可以做到跨平台。
腳本是一種批處理文件的延伸,是一種純文本保存的程序,一般來說的計算機腳本程序是確定的一系列控制計算機進行運算操作動作的組合,在其中可以實現一定的邏輯分支等。
簡單地說,腳本就是一條條的文字命令,這些文字命令是可以看到的(如可以用記事本打開查看、編輯),腳本程序在執行時,是由系統的一個解釋器,將其一條條的翻譯成機器可識別的指令,並按程序順序執行。因為腳本在執行時多了一道翻譯的過程,所以它比二進製程序執行效率要稍低一些。
(2)寫腳本命令擴展閱讀:
一、腳本的特性:
1、語法和結構通常比較簡單;
2、學習和使用通常比較簡單;
3、通常以容易修改程序的「解釋」作為運行方式,而不需要「編譯」;
4、程序的開發產能優於運行效能。
二、腳本的應用:
1、作為批次處理語言或工作控制語言。許多腳本語言用來執行一次性任務,尤其是系統管理方面,DOSWindows的批處理文件和Unix的shell腳本都屬於這種應用;
2、作為通用的編程語言存在,如Perl、Python、Ruby等。由於「解釋執行,內存管理,動態」等特性,它們仍被稱為腳本語言。但它們已經用於應用程序編寫,用戶也不把它們看作腳本語言;
3、許多大型的應用程序都包括根據用戶需求而定製的慣用腳本語言。同樣地,許多電腦游戲系統使用一種自定義腳本語言來表現NPC(Non-Player Character,Non-Playable Character,Non-Player Class)和游戲環境的預編程動作。
此類語言通常是為一個單獨的應用程序所設計,雖然它們貌似一些通用語言(如Quake C,Modeled After C),但它們有自定義的功能。
C. 如何寫exp和imp腳本命令
EXP/IMP備份(導出/導入備份)
exp hely=y 說明:
USERID 用戶名/口令
FULL 導出整個文件 (N)
BUFFER 數據緩沖區的大小
OWNER 所有者用戶名列表
FILE 輸出文件 (EXPDAT.DMP)
TABLES 表名列表
COMPRESS 導入一個范圍 (Y)
RECORDLENGTH IO 記錄的長度
GRANTS 導出許可權 (Y)
INCTYPE 增量導出類型
INDEXES 導出索引 (Y)
RECORD 跟蹤增量導出 (Y)
ROWS 導出數據行 (Y)
PARFILE 參數文件名
CONSTRAINTS 導出限制 (Y)
CONSISTENT 交叉表一致性
LOG 屏幕輸出的日誌文件
STATISTICS 分析對象 (ESTIMATE)
DIRECT 直接路徑 (N)
TRIGGERS 導出觸發器 (Y)
FEEDBACK 顯示每 x 行 (0) 的進度
FILESIZE 各轉儲文件的最大尺寸
QUERY 選定導出表子集的子句
下列關鍵字僅用於可傳輸的表空間
TRANSPORT_TABLESPACE 導出可傳輸的表空間元數據 (N)
TABLESPACES 將傳輸的表空間列表
imp hely=y 說明:
USERID 用戶名/口令
FULL 導入整個文件 (N)
BUFFER 數據緩沖區大小
FROMUSER 所有人用戶名列表
FILE 輸入文件 (EXPDAT.DMP)
TOUSER 用戶名列表
SHOW 只列出文件內容 (N)
TABLES 表名列表
IGNORE 忽略創建錯誤 (N)
RECORDLENGTH IO 記錄的長度
GRANTS 導入許可權 (Y)
INCTYPE 增量導入類型
INDEXES 導入索引 (Y)
COMMIT 提交數組插入 (N)
ROWS 導入數據行 (Y)
PARFILE 參數文件名
LOG 屏幕輸出的日誌文件
CONSTRAINTS 導入限制 (Y)
DESTROY 覆蓋表空間數據文件 (N)
INDEXFILE 將表/索引信息寫入指定的文件
SKIP_UNUSABLE_INDEXES 跳過不可用索引的維護 (N)
ANALYZE 執行轉儲文件中的 ANALYZE 語句 (Y)
FEEDBACK 顯示每 x 行 (0) 的進度
TOID_NOVALIDATE 跳過指定類型 id 的校驗
FILESIZE 各轉儲文件的最大尺寸
RECALCULATE_STATISTICS 重新計算統計值 (N)
下列關鍵字僅用於可傳輸的表空間
TRANSPORT_TABLESPACE 導入可傳輸的表空間元數據 (N)
TABLESPACES 將要傳輸到資料庫的表空間
DATAFILES 將要傳輸到資料庫的數據文件
TTS_OWNERS 擁有可傳輸表空間集中數據的用戶
導入注意事項:
(1) 資料庫對象已經存在
一般情況, 導入數據前應該徹底刪除目標數據下的表, 序列, 函數/過程,觸發器等;
資料庫對象已經存在, 按預設的imp參數, 則會導入失敗
如果用了參數ignore=y, 會把exp文件內的數據內容導入
如果表有唯一關鍵字的約束條件, 不合條件將不被導入
如果表沒有唯一關鍵字的約束條件, 將引起記錄重復
(2) 資料庫對象有主外鍵約束
不符合主外鍵約束時, 數據會導入失敗
解決辦法: 先導入主表, 再導入依存表
disable目標導入對象的主外鍵約束, 導入數據後, 再enable它們
(3) 許可權不夠
如果要把A用戶的數據導入B用戶下, A用戶需要有imp_full_database許可權
(4) 導入大表( 大於80M ) 時, 存儲分配失敗
默認的EXP時, compress = Y, 也就是把所有的數據壓縮在一個數據塊上.
導入時, 如果不存在連續一個大數據塊, 則會導入失敗.
導出80M以上的大表時, 記得compress= N, 則不會引起這種錯誤.
(5) imp和exp使用的字元集不同
如果字元集不同, 導入會失敗, 可以改變unix環境變數或者NT注冊表裡NLS_LANG相關信息.
導入完成後再改回來.
(6) imp和exp版本不能往上兼容
imp可以成功導入低版本exp生成的文件, 不能導入高版本exp生成的文件
使用方法:
例題格式及說明:
1.普通資料庫全部導出和導入
exp 用戶/密碼@dbName file=路徑.dmp full=y --還有其他的參數,看需要進行填寫
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log full=y commit=y ignore=y --全部導出
$ imp user/pwd file=/dir/xxx.dmp log=xxx.log fromuser=dbuser touser=dbuser2 --全部導入
2.指定用戶全部導出
/home/oracle/proct/9.2.0.4/bin/exp userid=用戶/密碼 --說明:本地的資料庫登入(可以指定其他資料庫,則需添加@dbName)
owner=導出的用戶名 file=導出路徑存放目錄.dmp log=導出的日誌信息.log --主要:這是不能使用full=y或則會出錯(默認該用戶全導出)
3.文件參數導出
$ exp parfile=username.par // 在參數文件中輸入所需的參數
參數文件username.par 內容
userid=username/userpassword
buffer=8192000
compress=n
grants=y
file=/oracle/test.dmp
full=y
4.制定表導出(分區表導出及條件表導出)
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log tables=table1,table2 --或tables(table1,table2,.....)
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log tables=(T1: table1,T2: table2,.....) --T1是分區表
$ exp scott/tiger tables=emp query=/"where job=/'salesman/' and sal/<1600/" file=/directory/scott2.dmp 或根據參數文件進行導出
5.導入(一張或多張表)
$ imp user/pwd file=/dir/xxx.dmp log=xxx.log tables=(table1,table2) fromuser=dbuser
touser=dbuser2 commit=y ignore=y
$ imp user/pwd file=/dir/xxx.dmp log=xxx.log fromuser=dbuser touser=dbuser2
commit=y ignore=y
6.只導出數據對象不導出數據
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log owner=user rows=n --rows=n/y說明是否導出數據行
7.分割多個文件導出和導入
$ exp user/pwd file=1.dmp,2.dmp,3.dmp,… filesize=1000m log=xxx.log full=y
$ imp user/pwd file=1.dmp,2.dmp,3.dmp,… filesize=1000m tables=xxx fromuser=dbuser
touser=dbuser2 commit=y ignore=y
8.增量導出和導入
a.完全增量導出(inctype=complete) // 備份整個資料庫
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log inctype=complete
b.增量型增量導出 導出上一次備份後改變的數據(inctype=incremental)。
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log inctype=incremental
c.累計型增量導出(Cumulative) 只導出自上次"完全"導出之後資料庫中變化的信息。
$ exp user/pwd file=/dir/xxx.dmp log=xxx.log inctype=cumulative
d.增量導入:
$ imp usr/pwd FULL=y inctype=system/restore/inctype --(SYSTEM: 導入系統對象,RESTORE: 導入所有用戶對象)
9.使用sysdba進行導出和導入
1. 命令行方式:
A: Windows平台:
C:/> exp 'sys/sys@instance as sysdba' tables=scott.emp file=e:/emp.dmp
B: Unix & Linux平台(這時的"'"需要用到轉義字元"/"):
$ exp /'sys/change_on_install@instance as sysdba/' tables=scott.emp file=/home/oracle/emp.dmp
C: 表空間導入和導出
$ imp /'usr/pwd@instance as sysdba/' tablespaces=xx transport_tablespace=y
file=xxx.dmp datafiles=xxx.dbf
2. 交互輸入方式:
exp tables=scott.emp --不輸入連接字元串,直接回車
Export: Release 10.2.0.3.0 - Proction on Fri Jun 25 07:39:46 2004 Copyright (c) 1982, 2005, Oracle. All rights reserved.
Username: sys/change_on_install@instance as sysdba --輸入連接字元串.
3.如果是寫在參數文件中,則連接字元串需要用雙引號了:USERID="sys/change_on_install@instance as sysdba"
10.表空間傳輸(建議:10g以上使用,但我試了在9i沒有找到相對應的檢查表空是否傳輸的語句,10g 支持跨平台的表空間傳輸)
注意:
l.索引在待傳輸表空間集中而表卻不在。(注意,如果表在待傳輸表空間集中,而索引不在並不違反自包含原則,當然如果你堅持這樣傳輸的話,會造成目標庫中該表索引丟失)。
2.分區表中只有部分分區在待傳輸表空間集(對於分區表,要麼全部包含在待傳輸表空間集中,要麼全不包含)。
3.待傳輸表空間中,對於引用完整性約束,如果約束指向的表不在待傳輸表空間集,則違反自包含約束;但如果不傳輸該約束,則與約束指向無關。
4.對於包含LOB列的表,如果表在待傳輸表空間集中,而Lob列不在,也是違反自包含原則的。
a.查看錶空間包含那些XML文件
select distinct p.tablespace_name
from dba_tablespaces p, dba_xml_tables x, dba_users u, all_all_tables t
where t.table_name = x.table_name
and t.tablespace_name = p.tablespace_name
and x.owner = u.username
b.檢測一個表空間是否符合傳輸標準的方法:
SQL > exec sys.dbms_tts.transport_set_check('tablespace_name',true);
SQL > select * from sys.transport_set_violations;
c.簡要使用步驟
1.設置表空間為只讀(假定表空間名字為APP_Data 和APP_Index)
SQL > alter tablespace app_data read only;
SQL > alter tablespace app_index read only;
2.發出EXP 命令
SQL> host exp userid='''sys/password as sysdba''' transport_tablespace=y
tablespaces=(app_data, app_index)
以上需要注意的是:(或則參考我自己寫的 表空間導入和導出例題)
·為了在SQL中執行EXP,USERID 必須用三個引號,在UNIX 中也必須注意避免"/"的使用
·在816 和以後,必須使用sysdba 才能操作
·這個命令在SQL中必須放置在一行(這里是因為顯示問題放在了兩行)
3.拷貝.dbf數據文件(以及.dmp 文件)到另一個地點,即目標資料庫可以是cp(unix)或(windows)或通過ftp 傳輸文件(一定要在bin方式)
4.把本地的表空間設置為讀寫
$ alter tablespace app_data read write;
$ alter tablespace app_index read write;
5.在目標資料庫附加該數據文件 (直接指定數據文件名)
(表空間不能存在,必須建立相應用戶名或者用fromuser/touser)
$ imp file=expdat.dmp userid=」」」sys/password as sysdba」」」
transport_tablespace=y datafiles=(「c:/app_data.dbf,c:/app_index.dbf」)
tablespaces=app_data,app_index tts_owners=hr,oe
6.設置目標資料庫表空間為讀寫
$ alter tablespace app_data read write;
$ alter tablespace app_index read write;
11.優化IMP/EXP的速度(修改參數配置文件)
EXP:
加大large_pool_size,可以提高exp 的速度
採用直接路徑的方式(direct=y),數據不需要經過內存進行整合和檢查.
設置較大的buffer,如果導出大對象,小buffer 會失敗。
export文件不在ORACLE 使用的驅動器上,不要export到NFS 文件系統
UNIX環境:用管道模式直接導入導出來提高imp/exp 的性能
IMP:
建立一個indexfile,在數據import完成後在建立索引
將import 文件放在不同的驅動器上
增加DB_BLOCK_BUFFERS
增加LOG_BUFFER
用非歸檔方式運行ORACLE:ALTER DATABASE NOARCHIVELOG;
建立大的表空間和回滾段,OFFLINE 其他回滾段,回滾段的大小為最大表的1/2
使用 COMMIT=N
使用ANALYZE=N
單用戶模式導入
UNIX環境:用管道模式直接導入導出來提高imp/exp 的性能
12.通過unix/Linux PIPE管道加快exp/imp速度
步驟如下:
通過管道導出數據:
1.通過mknod -p 建立管道
$ mknod /home/exppipe p // 在目錄/home下建立一個管道exppipe注意參數p
2.通過exp 和gzip 導出數據到建立的管道並壓縮
$ exp test/test file=/home/exppipe & gzip < /home/exppipe > exp.dmp.gz
$ exp test/test tables=bitmap file=/home/newsys/test.pipe &
gzip < /home/newsys/test.pipe > bitmap.dmp.gz
3.導出成功完成之後刪除建立的管道
$ rm -rf /home/exppipe
4.shell腳本可以這樣寫(我只是寫主要的)
unix下:
mkfifo /home/exp.pipe
chmod a+rw exp.pipe
compress < exp.pipe > exp.dmp.Z &
su -u oracle -c "exp userid=ll/ll file=/home/exp.pipe full=y buffer=20000000"
rm exp.pipe
linux下:
mknod /home/exppipe p
$ imp test/test file=/home/exppipe fromuser=test touser=macro &
gunzip < exp.dmp.gz > /home/exppipe
$ rm –fr /home/exppipe
D. 如何使用快捷指令寫腳本
1. 場景
相信大部分同學早上醒來之後,都是手動打開音樂軟體,播放自己喜歡的音樂,然後手動滑動屏幕,查看今天的天氣,日復一日,生活顯得特別的朴實無華且枯燥
試想一下,如果清晨醒來時,按掉鬧鈴後能自動化語音播放今日天氣,隨機播放自己喜歡的音樂,給自己帶來元氣滿滿的一天,這種感覺不要太爽!
本篇文章將為大家推薦這款 iOS 端的自動化應用,快捷指令 App,可以通過它創建快捷指令及自動化指令集合,快速來完成來各種任務,提升我們的效率
2. 介紹
之前寫過一款 Android 端的自動化軟體:Tasker,點我查看
快捷指令是 iOS 端的一款 App,功能與 Tasker 類似,可以基於時間、位置、打開某個 App 等場景,將一個功能設置為快捷指令,最後通過點擊或者 Siri 快速調用任務
image
另外,快捷指令可以創建強大的自動化任務,合並多個應用之間的步驟,完成復雜的自動化場景
3. 實戰
以第一段要實現的場景為例第 1 步,創建一個鬧鍾
image
第 2 步,創建獲取天氣的快捷指令打開快捷指令 App,沒有安裝的同學,可以去 App Store 手動下載安裝
在 App 首頁,點擊右上角的 + 號來添加一個「新的快捷指令」,然後就可以添加具體的操作了
image
ps:添加操作建議通過搜索框關鍵字,快速進行添加輸入關鍵字「定位」,選擇「選擇獲取當前位置」這一項,完成第一條操作的添加
image
然後,輸入關鍵字「天氣」,選擇「獲取當前天氣」這一欄
image
接著,搜索關鍵字「文本」,插入一個文本操作,單擊文本操作區,編輯文本內容從上面步驟中的「當前位置」得到城市、從「天氣狀況」獲取最高溫度和最低溫度,最後經過組裝成一段天氣語句
image
緊接著,輸入關鍵字「朗讀文本」,這個操作可以將上面文本框內的內容朗讀出來
點擊右下角的執行按鈕,可以執行這條快捷指令
image
測試沒有問題後,點擊下一步,對這條快捷指令重命名,保存後的快捷指令會出現在首頁捷徑列表中第 3 步,創建自動化流程點擊底部的自動化標簽欄,然後選擇「創建個人自動化」,創建一個自動化任務
image
首先,設置觸發條件
選擇日程中的鬧鍾,設置自動化任務觸發條件為「鬧鍾停止時」,並指定第 1 步創建的鬧鍾
image
然後,設置執行動作
設置執行
E. 製作自己的腳本命令
其實這個任務用 awk 很容易完成的,不需要寫腳本:
awk -F '\t' -v f=2 'a[$f] { printf("field %d of line %d and %d are the same.\n", f, a[$f], NR); exit 1 } { if (f > NF) exit 2; a[$f] = NR}' filename
如果非要做成腳本的話,其實就是加了個參數處理,可以這樣寫(有重復的返回1,沒重復的返回0,有錯誤返回2):
#!/bin/sh
# -d
DELIMITER="\t"
# -f
FIELD=0
FILE=""
# help
usage() {
cat <<EOF
Usage: $(basename $0) [OPTIONS]... [FILE]
Determine if field is uniq.
Options:
-d, --delimiter DELIMITER specify the delimiter, default: '\\t'
-f, --field FIELD specify the field, default: whole line.
-h, --help display this help and exit
EOF
}
# main
while [ $# -gt 0 ]; do
case "$1" in
'-d' | '--delimiter')
DELIMITER="$2"
shift 2
;;
'-f' | '--field')
FIELD="$2"
if echo "$2" | grep -qv '^[0-9]$'; then
echo '-f takes a number!' >&2
exit 2
fi
shift 2
;;
'-h' | '--help')
usage
exit 0
;;
*)
if [ -z "$FILE" ]; then
FILE="$1"
shift 1
else
echo 'Only support one file!' >&2
exit 2
fi
;;
esac
done
awk -F "$DELIMITER" -v f="$FIELD" '
a[$f] {
# 如果想輸出重復的那一行的內容的話,可以直接 print
printf("field %d of line %d and %d are the same.\n", f, a[$f], NR)
exit 1
}
{
if (f > NF) exit 2
a[$f] = NR
}' "$FILE"
F. 如何用xshell編寫腳本
1、在編寫shell腳本的時候一般會先查詢伺服器可以使用哪種腳本,並且查看伺服器使用的默認腳本方式是哪一種。
G. 求腳本(BAT)基本命令
1.「@echo off」--我們所寫的BAT一開始一般都有這一句,這一句的作用是:使所有的命令響應隱藏。「@」--本行命令不回顯。(本來如果你用echo off就可以了,但是還是能夠看到echo off這條命令在CMD下,影響美觀) 2.「color 1e」--設置默認的控制台前景和背景顏色。當前我設為藍底黃字,具體顏色請在CMD下用「color /?」查詢。 --這里又提到了這個參數「/?」,一般CMD下命令後加「/?」就會顯示這條命令的幫助。 3.「rem」--注釋作用,批處理執行過程中前不執行它,rem 後的字元只作注釋作用。
4.「title」--設置命令提示窗口的窗口標題。默認為「cmd」。改成自己喜歡的多有個性,嘿嘿。
5.「cls」--不多說,清屏命令。主要是怕前面的一些空白或字元出現影響美觀。
6.「set」--這個命令的作用很大,請用「set /?」查詢具體使用方法。本例「set topip=172.16.」是將一個名為「topip」的變數值設為「172.16.」。注意CMD下變數的設置不區別數字與字元,能夠自動根據提供的值調整。下行「set theip=0.0」同理。
7.「echo .」--在新行中顯示一個「.」。echo命令能顯示其後的comment。這里提幾個有趣實用的用法--「echo.」,注意與前面的不同,「echo」與「.」間無空格。這條命令如同一個回車,在新行不顯示任何信息並換行。「echo 」,實現響鈴的提示音。後面一個字元的輸入方法是在CMD下用「ctrl+G」,而這個字元得到的方法是CMD下用命令「echo "ctrl+G" >ex.txt」,存入ex.txt文件,再從那裡提取出來的。嘿嘿,如果你懶得做,就我在上面提供的字元嘍。
8.「if」--這條命令也會經常用到,請用「if /?」學習更多信息。本例「if not exist scanipc.exe (echo 文件錯誤!……) 」,實現功能:當同級目錄下不存在「scanipc.exe」時,提示「文件錯誤!……」。否則不提示。「if not exist filename 」在批處理中使用比較多些。
9.「:top」,設置一個標志點,標志名為「top」。「:」的作用就是設置標志。網上有文章說「使用"::comment"作為注釋比"rem comment"執行效率更高。」我相信,這里也建議大家,如果BAT中注釋較多時,請使用「::comment」設置。
10.「set /p pno=」--設置一個變數,並接受用戶輸入。BAT不需要預先聲明變數,只在需要時設置。參數「/p」:將變數數值設成用戶輸入的一行輸入。
11.「if %pno% gtr 9 gotoonerrorspno」--檢驗用戶輸入值是否大於9,是,則轉到一個指定標志點。這里注意BAT中變數引用時要在前後加「%」,但在if語句中可有可無,具體應用大家多寫幾遍就有體會。
12.「goto label」--無條件跳轉到指定標志位並向後執行。BAT好像只有這么一個跳轉語句了,作用不用我說,用了就知道。注意不要構成死循環。
小結:到此,完成了顏色設置、注釋版權說明、標題設置、變數初始化、歡迎信息、功能界面初始化、標志點設置(因為歡迎信息只顯示一次而功能界面要多次使用所以將標志點設置在歡迎信息的後面。)命令的接受與跳轉。;功能界面一般要用「tab」鍵調整相對位置,才能起到美觀的效果。請多練習幾遍領會。;大家在寫腳本過程中要注意標志點的設置位置,才能起到合適的效果。一般寫過幾個腳本會有些感受。;接著接受用戶輸入後「cls」清屏開始執行指定功能。注意這個cls的作用。因為清屏可以在此時,也可以在每個命令執行之前,但如果在每個命令執行之前用的請,那麼要寫的cls就多了,於是把cls寫在這里合適,方便節約快捷。
大家在寫腳本時也應當注意這方面的技巧,將使你寫出更加高效節約方便的代碼。在每次寫完腳本後合理地整合一下自己的代碼。能積累不少經驗。;另外,鑒於部分人仍不知道如何建立BAT文件與運行,請:打開記事本,寫入代碼,保存,保存類型為「所有文件*.*」,文件名為「name*.BAT」。保存後,雙擊運行。因為一般BAT運行很快,所以你可能只看到窗口一閃就消失了,那麼你可以在exit 之前加pause確保能看見運行結果。到此,你應該能夠寫一個很簡單的腳本了,實現一些界面控制。
例1: @echo off color ca title 這是我第一個BAT腳本。 echo 這是我第一個BAT腳本。不錯啊。 pause >nul exit 第二節:(提一些好用的命令)以下設置的都是功能段,在「goto step%pno%」跳轉到相應功能段後,開始執行相應功能。一般命令段: step1:ping命令。(在echo中變數的引用請注意前後加「%」號,否則會導致程序出錯。)我們常用的ping命令:其實很簡單,自己看幫助啦。本句「ping %topip%%theip% -n 1 |findstr 100%>nul」將ping 只發送一次數據包,這樣命令執行起來就快多了,但這樣所會引起一定概率的誤判,而我們在內網這種概率很低,低到可以忽略。所以本人使用參數「-n 1」減少執行時間。將結果不回顯而通過管道命令「|」送給findstr分析,findstr查找是否存在「100%」,並將回顯「丟棄」--「>nul」。因為如果ping一台主機如果返回的結果有「100%」存在說明「不在線。或者有防火牆阻擋。」。所以用findstr確定字元串「100%」的存在性,因為 findstr也有回顯,但我們並不需要,所以將它「丟棄」,使用參數「>nul」將指定命令回顯丟棄。(這一句命令是重點,請仔細領會。)又因為findstr確定指定字元串的存在性後會設定環境變數「errorlevel」的值,所以我們根據「if %errorlevel% equ 0 (command)」,判斷findstr的執行結果就行了,也就不需要有回顯。 「errorlevel」作用很大,一般命令行下的命令執行後都有一個特別的errorlevel,我們就可以根據相應的「返回值」作出相應判斷並執行相應功能。findstr如果找到指定字元串,則有errorlevel=0,說明:IP不在線。那麼既然不在線,我們就沒有向下執行的必要了,直接跳回top界面功能接受下一次指令。如果IP有不同回應,說明在線,則開始檢測共享。「net view \\%topip%%theip%\」--查看指定IP的共享清單。net詳細命令請自行查閱。列出共享清單後返回功能界面。 step2:打開共享一。「explorer \\%topip%%theip%\」,用資源管理器打開指定的IP根。注意語法,其它也沒有什麼。 step3:IPC$空連接。「net use \\%topip%%theip%\ipc$ "" /user:"administrator"」,一個很老的漏洞,但也許內網還有機子存在哩,嘿嘿,語法就是這樣。 step4:一般信息。「ipconfig /all」--用於得到本機的IP與MAC等信息,很好用的命令。語法如示。 「nbtstat -na %topip%%theip%」--用於得到他方機子的一些信息,語法如示。另請自查幫助。 step5:Scanipc。用命令行打開了一個程序而已。在命令行下執行其它命令也就是這樣啦。 step6:返回時間。「net time \\%topip%%theip%」--探測指定機子時間,語法如示。 step7:遠程連接。「net use \\%topip%%theip%\admin$ "" /user:"administrator"」,嘿嘿,administrator空密碼連接。最簡單的入侵啦,嘿嘿嘿。語法如示。 step8:本機信息。跳到另一個功能界面執行相應功能。 step9:高級命令。跳到另一個功能界面執行相應功能。 step0:退出程序。一個exit退出腳本。「exit」,退出CMD。 onerrorsip:實現錯誤提示,並重新執行step1。 onerrorspno:實現錯誤提示,並重新跳轉到功能界面。高級命令段:引用前面已給定的IP,並對其進行一些高級操作。重新繪制功能界面。首先,注意在一個BAT文件中,不允許出現有標志名的重復。 step11:條件連接。設定兩個變數,分別為用戶名與密碼。注意到有一個默認的功能。實現原理是,當接受到用戶輸入為空時(即一個回車),變數將保持不變。條件連接語法如示。比前面遠程空密碼連接更高級一點,嘿嘿。 step12:打開共享。打開已經連接成功的對方計算機的指定盤。打開指定盤語法如示。 step13:發送消息。向對方發送消息。要求雙方的messager服務開啟,否則無法發送成功。發送消息語法如示。 step14:遠程關機。設置關機時間與關機理由,用shutdown程序關閉對方計算機,嘿嘿,惡作劇。要求你連接成功,並有 shutdown程序支持。shutdown語法自查幫助。 step15:溢出CMD。嘿嘿,溢出到對方的CMD下,算是一個真正的入侵了。當然需要用戶名與密碼嘍。要求用戶名與密碼正確並對方默認支持遠程管理。並有psexec程序支持。psexec語法如示,並請自查幫助。 step16:結束進程。嘿嘿,不說也知道,結束對方已知進程。要求連接成功並有pskill程序支持。惡作劇類,有惡意成分。嘿嘿。小心使用。 step17:ipc$連接。同step3. step18:斷開連接。斷開與對方的連接,就是擦屁股啦,以免讓對方有所察覺。這個好習慣要養成。語法如示。 step19:一般命令。返回前面一個功能界面。 step20:結束程序。退出。 step110:AT命令,令對方在指定時間運行指定命令。有點像木馬,嘿嘿。要求連接成功。因為節約變數,所以引用了前面的暫不使用的變數。好習慣。哈哈。 step111:telnet。遠程telnet。不要說你一點都不知道,語法如示並請自查幫助。 step112:更改主IP。主要是為了使我們的使用方便,對某個特定IP段探測能夠簡化輸入。如主IP改成「172.16.130.」,那麼專門對130探測,而且輸入IP時只需輸入最後位,嘿嘿,多方便啊。 step113:任意命令。主要是接受用戶輸入並執行用戶的輸入罷了,結構如示。本機信息段:主要是對本機信息的一些查詢語法。 stepm1:ipconfig,不說了。但請注意到,在功能界面的實現上有一點,「&」符號,因為「&」符號在CMD下是命令連接符,如果光用「&」會讓BAT誤解為其後的都是命令。但我們只是希望輸出一個「&」罷了,於是用「^」符號連接符表明只是輸出「&」,而不是實現命令連接。這里提一下「&」命令連接符,例如:echo frist&echo second.同效於: echo frist echo second. 只是實現結合兩行命令在同一行實現。類如一個很簡單的批處理啦。再提一下「^」符號連接符,對一些特殊符號可能在CMD下無法正確如願顯示,可用「^」連接,以達到如期效果。用了「^」在文本中佔了一位空間,但在輸出時它並不顯示,所以注意界面的布置。 stepm2:本機進程。利用命令行下的進程工具查看進程。要求pslist程序支持。 stepm3:本機用戶。就是查詢一下本機用戶,也許會發現機了被動過的痕跡。 stepm4:結束進程。在命令行下結束本機進程。要求有pskill程序支持。 stepm5:本機埠。也許能看出被攻擊或被入侵的痕跡。語法如示。 stepm6:共享情況。看看本機的共享是否真的如你所想,如你所見。否則請注意安全嘍。語法如示。 stepm7:啟動項值。在命令行下導出啟動項值並給出結果。比魔法兔子什麼的快多了,就是界面不是很好看,呵呵。語法如示。 stepm0:退出程序。退出。小結:到此,您學習過了一些有用的命令與應用。以及大部分的網路命令與外部程序的使用。接下來你可以模擬IP小工具寫出適合更自己的IP小工具哦。注意每執行完一項功能後要用goto返回功能界面,否則腳本無條件向下繼續執行。;errorlevel的應用。在BAT中,errorlevel的作用很大,大家在使用過程中通過多次接觸,感受一下如何玩轉errorlevel。在執行完一個程序後,可以用echo %errorlevel%查看程序運行後是如何設定errorlevel的值。;if的應用。在BAT中,if語句的作用也很大,特別與errorlevel結合實現自動判斷。以及一些基本條件判斷。請查看"if /?" 學習更詳細的說明。;變數的接受與傳遞。這方面的感覺需要大家多寫BAT才能有所感觸。如何合理與高效的應用變數,能使你的腳本更加漂亮。計算機語言都是實踐性很強的,我們學習理論只是基礎,通過大量的實踐才能真正掌握一門語言的應用。 第三節:(一些應用技巧與命令)接下來我們看我的「代理伺服器搜索組件 (ver 2.1)」, 1.「>」與「>>」的區別。 「>」--把指定數據傳送到指定文件或區域。有覆蓋作用,從文件頭開始重寫文件。如指定文件不存在,則新建文件並存入指定數據。 「>>」--以追加方式將指定數據傳送到指定文件或區域。從文件結尾開始寫入指定內容。這兩個功能有區別,請注意選擇合適的傳送方式傳送數據。例如:「echo 文本內容。>link.txt」與「echo 文本內容。>>link.txt」。若本不存在文件link.txt或文件link.txt內容為空,那麼兩條命令的運行結果相同。但如果link.txt不為空,那麼第一條命令將清除link.txt所有內容並存入數據「文本內容。 」保存。而第二條命令只在link.txt的文件尾(另起一行,注意每一個「>>」都會另起一行寫入新數據)追加數據「文本內容。」而以前的內容保持不變。還要特別提一個前面說過的「丟棄」用法「>nul」,因為我們有時候只需要命令的運行而並不需要看到命令的運行結果以及回顯,但這些命令又會出現我們並不需要看到的回顯,影響美觀。故在其後追加「>nul」,丟棄回顯。 2.循環語句的說明。例2: :puship set /p tip= if %tip%==%tbip% goto step1 set tbip=%tip% echo %tip% >>link.txt goto puship 本例中「if %tip%==%tbip% goto step1」與「if %tip% equ %tbip% goto step1」效果一樣。本例的作用是接受用戶帖入數據。關鍵技術在於:因為用戶帖入數據我們不能使用戶每次輸入都詢問是否結束,而需要實現「 智能化」的判斷,但如何以最少的代碼、最簡單的方法實現所謂的「智能化」呢。分析用戶輸入情況:因為一般用戶帖入數據都不會出現重復,所以我們利用這個特點,分析用戶的數據,當用戶帖入列表時,分析數據並將數據存入相應文本,以備後用。當用戶粘帖文本結束後,再加一個回車,因為最後一次變數沒有接受到任何修改,於是保持默認不變(也就是之前的數據。),再通過我們之前的數據備份對照,分析是否不變,是,則跳出循環。這樣,我們通過兩個變數以一個IF比較實現相對簡單的「智能化」。嘿嘿,這一點代碼想了我一個小時。這么說不知道大家是否能理解。請仔細參透例2的技術要點。 3.「FOR /F "eol=; tokens=1 delims=: " %%i in (link.txt) do (set /a Allip=Allip+1>nul)」 這句FOR語句是復雜的雜合語句。首先請用for /?查閱詳細用法,這里不再復述。但是特別要提一點的就是批處理與直接命令行下的CMD的區別在FOR語句上。批處理時,變數引用需要有兩個「%」號,否則無法正確執行,而CMD下不用,只需一個「%」。 「set /a Allip=Allip+1>nul」--實現算術運算,變數Allip的自增,注意大小寫。把回顯「丟棄」。本例實現對文件link.txt內容計數,忽略以「;」開頭的行。這就是為什麼我們在前面要用「echo ;:文本>link.txt」來創建文本的意義所在。 4.「call toping %%i」--從批處理程序調用另一個批處理程序。調用另一個批處理「toping.bat」(因為BAT可以直接運行所以不需要後綴BAT),並有參數傳遞。參數來自於FOR語句的提取。「FOR /F "eol=; tokens=1 delims=: " %%i in (link.txt) 」--從link.txt的每行中提取文本,從每行的開頭第一個字元開始(tokens=1),以「:」界定提取結尾(delims=: )。把提取結果賦給變數i。 5.「type」--在命令行下顯示指定文件的內容。相信大家應該很熟悉,不多說了。注意與「>或>>」的結合使用,或與其它操作符的結合使用。 6.「%1」--在CMD下,一個BAT能夠接受同時9位的參數,「%1~%9」,分別對應給定的參數變數。「%0」,即是文件本身。我們在使用BAT的過程中會經常遇到兩個或兩個以上腳本間需要參數傳遞。那麼請好好掌握這個用法,多說無益,需要大家在實踐中積累經驗。 7.再說一些比較邊緣,但大家比較興趣的命令。呵呵,不要做壞事。 net user admin 123 /add net localgroup administrators admin /add net localgroup users admin /del net user admin /active:yes net user net user admin net user admin /del 「net user admin 123 /add」--添加名為「admin」,密碼為「123」的用戶,如果「123」不寫,則默認密碼為空。 「net localgroup administrators admin /add」--將用戶「admin」加入「administrators」組,嘿嘿,高許可權。 「net localgroup users admin /del」--將「admin」從「users」組刪除。呵呵,因為用戶新加進去時都是「users」組,許可權比較低,所以要從這個組跳出來,保證administrators組的許可權正式發揮作用,如果不這么做,對方系統會默認你的最低許可權。 「net user admin /active:yes」--怕沒法使用沒有啟動,不要緊,激活這個帳號,嘿嘿。 「net user」--看看用戶有多少哦。 「net user admin」--看看剛剛加的用戶信息如何,是否如我所想,如我所願呢。 「net user admin /del」--刪除用戶admin。 -------------------------------------------------------------------------------------------------------------------
H. 腳本是怎麼寫出來的
腳本(Script)是一種批處理文件的延伸,是一種純文本保存的程序,一般來說的計算機腳本程序是確定的一系列控制計算機進行運算操作動作的組合,在其中可以實現一定的邏輯分支等。
腳本簡單地說就是一條條的文字命令,這些文字命令是可以看到的(如可以用記事本打開查看、編輯),腳本程序在執行時,是由系統的一個解釋器,將其一條條的翻譯成機器可識別的指令,並按程序順序執行。
因為腳本在執行時多了一道翻譯的過程,所以它比二進製程序執行效率要稍低一些。
(8)寫腳本命令擴展閱讀
腳本通常可以由應用程序臨時調用並執行。各類腳本被廣泛地應用於網頁設計中,因為腳本不僅可以減小網頁的規模和提高網頁瀏覽速度,而且可以豐富網頁的表現,如動畫、聲音等。
舉個最常見的例子,當點擊網頁上的Email地址時能自動調用Outlook Express或Foxmail這類郵箱軟體,就是通過腳本功能來實現的。
也正因為腳本的這些特點,往往被一些別有用心的人所利用。例如在腳本中加入一些破壞計算機系統的命令,這樣當用戶瀏覽網頁時,一旦調用這類腳本,便會使用戶的系統受到攻擊。
所以用戶應根據對所訪問網頁的信任程度選擇安全等級,特別是對於那些本身內容就非法的網頁,更不要輕易允許使用腳本。通過「安全設置」對話框,選擇「腳本」選項下的各種設置就可以輕松實現對腳本的禁用和啟用。
I. Linux裡面基本的shell腳本編寫有哪些
shell腳本就是一些命令的集合。
舉個例子,我想實現這樣的操作:
1)進入到/tmp/目錄;
2)列出當前目錄中所有的文件名;
3)把所有當前的文件拷貝到/root/目錄下;
4)刪除當前目錄下所有的文件。
簡單的4步在shell窗口中需要你敲4次命令,按4次回車。這樣是不是很麻煩?當然這4步操作非常簡單,如果是更加復雜的命令設置需要幾十次操作呢?那樣的話一次一次敲鍵盤會很麻煩。所以不妨把所有的操作都記錄到一個文檔中,然後去調用文檔中的命令,這樣一步操作就可以完成。其實這個文檔呢就是shell腳本了,只是這個shell腳本有它特殊的格式。《linux 就該這么學》
Shell腳本通常都是以.sh 為後綴名的,這個並不是說不帶.sh這個腳本就不能執行,只是大家的一個習慣而已。所以,以後你發現了.sh為後綴的文件那麼它一定會是一個shell腳本了。test.sh中第一行一定是 「#! /bin/bash」 它代表的意思是,該文件使用的是bash語法。如果不設置該行,那麼你的shell腳本就不能被執行。』#』表示注釋,在前面講過的。後面跟一些該腳本的相關注釋內容以及作者和創建日期或者版本等等。當然這些注釋並非必須的,如果你懶的很,可以省略掉,但是筆者不建議省略。因為隨著你工作時間的增加,你寫的shell腳本也會越來越多,如果有一天你回頭查看你寫的某個腳本時,很有可能忘記該腳本是用來干什麼的以及什麼時候寫的。所以寫上注釋是有必要的。另外系統管理員並非你一個,如果是其他管理員查看你的腳本,他看不懂豈不是很郁悶。該腳本再往下面則為要運行的命令了。
J. 腳本怎麼寫
1、分析游戲需要的功能是根據需要寫代碼。
2、判斷用戶點擊,進入腳本前放點toast或者dialog提示框,放完這些之後將腳本初始化了,進入功能代碼。
3、由系統的一個解釋器,將其一條條的翻譯成機器可識別的指令,並按程序順序執行。因為腳本在執行時多了一道翻譯的過程,所以它比二進製程序執行效率要稍低一些。
腳本語言:
一般的腳本語言的執行只同具體的解釋執行器有關,所以只要系統上有相應語言的解釋程序就可以做到跨平台。含有bind和alias等命令的集合,這個集合存為一個獨立的文件然後在需要的時候執行,這樣就方便在CS中的使用。
腳本可以存為後綴名為cfg的文件放在cstrike文件夾下,執行時在控制台輸入exec腳本文件名cfg即可。比如將一個腳本存為 buyscfg文件,則在控制台中輸入execbuyscfg則可以實現所需要的功能。要實現一個命令只要把這一過程定義好,並且分配一個鍵位給這個命令。