1. 程式人生 > >shell 當前工作目錄的絕對路徑

shell 當前工作目錄的絕對路徑

@(Linux 命令指令碼)

編寫指令碼中,需要獲取執行指令碼的絕對路徑,今天寫指令碼的時候不小心踩了個坑,記錄下。

那個坑的指令碼大概是這樣的:

#!/bin/bash

work_path=$(dirname $0)
cd ~/${work_path}
## blblbl
cd /home/lcd/
cp ./something ${work_path}

問題就出在最後那句,本意我是希望把/home/lcd/something 複製到我指令碼的執行目錄。
假設我的指令碼目錄在/home/lcd/shell/下,

bash /home/lcd/shell/mytest.sh
# work_path -> home/lcd/shell
# 能得到想要的 lcd:/home/lcd/shell/ $ bash ./mytest.sh # work_path -> ./ # 所以上面的執行方式,something 還是複製到了./ # 也就是最後 cd 進去的目錄下

查了下,總結下獲取路徑的方法,以及可能的誤區。

  1. 指令碼引數 0使0 可以獲取到路徑,但不一定是絕對路徑,實際上, $0 是代表傳遞給 bash 這些的第一個引數。
$ bash ./mytest.sh 				# $0= ./mytest.sh
$ bash ./shell/mytest.sh 			# $0= ./shell/mytest.sh
$ bash /home/lcd/shell/mytest.sh	# $0= /home/lcd/shell/mytest.sh

如果執行的時候給的是絕對路徑,那麼我們可以通過 $0 提取到絕對路徑,實際上我們沒法保證。

  1. 使用 pwd 獲取路徑
    pwd 可以列印當前路徑,但是也不一定是指令碼的位置。
lcd:/home/lcd/shell/ $ bash ./mytest.sh 
# pwd=/home/lcd/shell/
lcd:/home/lcd/ $ bash ./shell/mytest.sh
# pwd=/home/lcd/
lcd:/root/ $bash /home/lcd/shell/mytest.sh
# pwd=/root/

可見,只有第一條的執行情況才滿足實際需要,pwd 列印的是你站在那裡,而不是指令碼在哪裡。

從上面兩點,看看下面這些獲取路徑的方法

# 在某些情況下會拿到錯誤結果
work_path=$(dirname $0)
work_path=$(pwd)

## 正確實現
# 通過 readlink 獲取絕對路徑,再取出目錄
work_path=$(dirname $(readlink -f $0))

# 或者曲線救國
work_path=$(dirname $0)
cd ./${work_path}  # 當前位置跳到指令碼位置
work_path=$(pwd)   # 取到指令碼目錄