2012-10-19 42 views
4

腳本需要的是使得bash腳本退出和打印錯誤消息,如果用戶調用腳本錯誤

#!/bin/bash 

# Check if there are two arguments 
if [ $# -eq 2 ]; then 
    # Check if the input file actually exists. 
    if ! [[ -f "$1" ]]; then 
    echo "The input file $1 does not exist." 
    exit 1 
    fi 
else 
    echo "Usage: $0 [inputfile] [outputfile]" 
    exit 1 
fi 

# Run the command on the input file 
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "$1" > "$2" 

編輯,腳本已更改爲

grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* 
if [ ! -f "$1" ]; then 

    echo 'Usage: ' 
    echo 
    echo './Scriptname inputfile > outputfile' 
    exit 0 

fi 

調用腳本不帶參數沒有給出誤差修改和坐在空白

Usage: 

./Scriptname inputfile > outputfile 

我的代碼

grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* 

此代碼拉那對他們的單個字線和泵輸出到一個新的文件,因此,例如

This is a multi word line 
this 
the above line is not 
now 
once again wrong 

輸出將是

This 
now 

該代碼的作品,用戶調用代碼使用./scriptname file > newfile

但是,我試圖展開代碼,以便在用戶錯誤地調用腳本時爲用戶提供錯誤消息。

對於錯誤messange,我想回顯scriptname file_to_process > output_file回來的東西。

我曾嘗試

if [incorrectly invoted unsure what to type] 
echo $usage 

exit 1 
Usage="usage [inputfile] [>] [outputfile] 

但是我有一點運氣。代碼運行,但如果我用腳本名稱調用,則什麼也不做。另外,如果我只用scriptname和輸入文件調用腳本,它將輸出結果而不是退出並顯示錯誤消息。

我試圖

其他的有

if [ ! -n $1 ]; then 

    echo 'Usage: ' 
    echo 
    echo './Scriptname inputfile > outputfile' 
    exit 0 

fi 

鑑於答覆到目前爲止,我已經收到,現在我的代碼是

#!/bin/bash 
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" $* 
if [ ! -f "$1" ]; then 

    echo 'Usage: ' 
    echo 
    echo './Scriptname inputfile > outputfile' 
    exit 0 

fi 

當調用腳本,而不輸入文件中的腳本不執行任何操作,並具有用ctrl + c中止,仍然嘗試獲取調用消息的回顯。

+0

你使用'/ bin/bash'還是'/ bin/sh'? –

+0

我正在使用bin/bash – Ausghostdog

+0

在命令行中使用'「$ @」'而不是'$ *';用空格保留文件名參數中的空格。如果在表達式前面使用'grep -P -e「...你的正則表達式」'-e「,那麼用戶可以在'-n'或'-l'上鍵入命令行和'grep'會適當地修改它的行爲。 (在GNU'getopt()'用來排列參數的系統上,你可能不需要指定'-e';我不喜歡那個特性。) –

回答

2

當您調用./scriptname file > newfile這樣的腳本時,shell會將file解釋爲./scriptname的唯一參數。這是因爲>是標準的輸出重定向操作符。

我想提出兩個可能的選擇:


替代1: 也許你可以嘗試把它當作1個論點也是這樣嗎?

./scriptname 'file > newfile' 

在這種情況下,檢查格式的一個方法是

#!/bin/bash 

# Check if the format is correct 
if [[ $1 =~ (.+)' > '(.+) ]]; then 
    # Check if the input file actually exists. 
    if ! [[ -f "${BASH_REMATCH[1]}" ]]; then 
    echo "The input file ${BASH_REMATCH[1]} does not exist!" 
    exit 1 
    fi 
else 
    echo "Usage: $0 \"[inputfile] [>] [outputfile]\"" 
    exit 1 
fi 

# Redirect standard output to the output file 
exec > "${BASH_REMATCH[2]}" 
# Run the command on the input file 
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "${BASH_REMATCH[1]}" 

注意:如果要檢查參數是否有效還是無效,這是一般最好只運行後命令檢查完成。


替代2: 傳遞2個參數一樣

./scriptname file newfile 

腳本看起來像這樣

#!/bin/bash 

# Check if there are two arguments 
if [ $# -eq 2 ]; then 
    # Check if the input file actually exists. 
    if ! [[ -f "$1" ]]; then 
    echo "The input file $1 does not exist." 
    exit 1 
    fi 
else 
    echo "Usage: $0 [inputfile] [outputfile]" 
    exit 1 
fi 

# Run the command on the input file 
grep -P "^[\s]*[0-9A-Za-z-]+.?[\s]*$" "$1" > "$2" 
+0

謝謝,唯一的問題是輸出是'Usage:$ 0 [inputfile] [>] [outputfile]'所以我只需要添加另一個否則在最後的fi之後和0出口是否正確? – Ausghostdog

+0

該腳本將運行'grep'並且如果'grep'成功運行,腳本將以狀態0退出,所以在腳本中實際上不需要'exit 0'(如果我理解你在說什麼......) ) – doubleDown

1

嘗試加雙引號$1和使用-f檢查存在,是正常的文件:

if [ ! -f "$1" ]; then 

    echo 'Usage: ' 
    echo 
    echo './Scriptname inputfile > outputfile' 
    exit 0 

fi 
+0

好吧我厭倦了使用'grep -P「^ [\ s] * [0-9A-Za-z-] +。[[s] * $」$ * if [! -f「$ 1」];然後 回聲「用法:」 回聲 回聲「./Scriptname inputfile中> OUTPUTFILE」 退出0 fi'的代碼時,我調用它只是坐在那裏一個什麼也沒做,我試着只用腳本名稱調用,已我錯過了使用代碼的東西。 – Ausghostdog

1

你也可以檢查與$#cat的用法信息帕拉姆計數:

if [ ! $# -eq 1 ]; then 
cat << EOF 
    Usage: 

    $0 'input_file' > output_file 
EOF 
    exit 1 
fi 
+1

而不是'[! $#-eq 1]'use'[$#-ne 1]' –

3

我會使用parameter expansion此:

inputfile=${1:?Usage: $(basename $0) inputfile > outputfile} 

如果腳本沒有參數被調用(即$1未設置)${var:?error message}擴展會導致shell在給定消息和退出時顯示錯誤。否則,第一個參數將被分配到$inputfile

+0

好問題 - 對於簡單的腳本來說,它是一種優雅的單線解決方案,對我來說效果很好,謝謝! – randomsock

+0

似乎你也可以通過腳本中的行分割錯誤信息,並且如果你需要更清楚地設置用法的格式,輸出將會反映相同的換行符 – randomsock