shell指令碼中報錯dirname:無效選項 -- b
今天在寫一個Shell指令碼的時候,發現調試的時候會報一個錯
[Oracle@smidb11 autoawrrpt]$ . a.sh dirname:無效選項 -- b請嘗試執行"dirname --help"來擷取更多資訊。basename:無效選項 -- b請嘗試執行"basename --help"來擷取更多資訊。
指令碼內容如下:
[oracle@smidb11 autoawrrpt]$ cat a.sh#!/bin/bash#################################################################################自動產生最新的AWR報表#版本:v1.0#變數說明:#LOGFILE:儲存記錄檔名####################################修改曆史#####################################################################################################################WORKDIR=$(dirname $0) #擷取到指令碼所在目錄cd ${WORKDIR} #改變目前的目錄為指令碼所在目錄WORKDIR=`pwd` #擷取目前的目錄的具體路徑SCRIPTNAME=$(basename $0) #擷取指令碼名稱FPATH="${WORKDIR}\${SCRIPTNAME}" #指令碼全路徑LOGFILE="${WORKDIR}/${SCRIPTNAME}.log" #設定記錄檔名稱AWR_TYPE="html" #設定AWR的類型,值應該為html或者txtAWR_HOME="${WORKDIR}/awr_report" #設定存放AWR報表的目錄AWR_DAYS=1 #設定AWR Snap檢索的天數HOSTNAME=`hostname` #主機名稱mkdir -p ${AWR_HOME} #如果沒有此目錄,則建立 -p選項代表無則建立,有則直接返回
報錯的是在 WORKDIR=$(dirname $0) 這一行內容,這讓我感覺很奇怪,第一,我沒有在這個命令後面添加-b選項啊,為什麼會報錯錯誤的選項 -b 呢?
然後在這行下面增加 echo $0 輸出,看看$0的內容到底是什麼
[oracle@smidb11 autoawrrpt]$ . a.shdirname:無效選項 -- b請嘗試執行"dirname --help"來擷取更多資訊。-bashbasename:無效選項 -- b請嘗試執行"basename --help"來擷取更多資訊。
這就奇怪了,$0 不是應該返回指令碼的當前路徑嗎? 怎麼會變成 -base 了呢?
我們接著實驗:
[oracle@smidb11 autoawrrpt]$ ./a.sh ./a.sh
直接運行,輸出結果變成正確的啦,$0輸出執行指令碼的相對路徑.
為什麼會導致這樣的問題呢?為了證明這個問題,我們直接在shell裡面運行 echo $0
[mysql@test ~]$ echo $0-bash
然後我們回顧一下,Linux下面的點命令
使用 點命令執行指令碼的時候,直接在當前的shell中執行指令碼,而不會開啟一個新的Shell執行指令碼
看到這裡我們就不難理解了。因為 . 命令不會開啟新的Shell執行指令碼,所以echo $0的時候,$0的值還是我們原來的shell的$0, 也就是 -bash 了, 而 basename命令就會把 -bash當成一個參數來執行,所以才會報錯,錯誤的選項 -b。
知道原因了,我們的問題也就很好解決了,直接運行,不要通過 點命令 或者 source 命令運行指令碼即可。
本文永久更新連結地址: