Mặc dù đây alias
là một cách để làm điều đó, nhưng điều này cũng có thể được thực hiện eval
- chỉ là bạn không muốn eval
thực thi lệnh như bạn muốn khai báoeval
lệnh .
Tôi thích alias
es - Tôi sử dụng chúng mọi lúc, nhưng tôi thích các chức năng tốt hơn - đặc biệt là khả năng xử lý các tham số của chúng và chúng không nhất thiết phải được mở rộng ở vị trí lệnh như yêu cầu cho alias
es.
Vì vậy, tôi nghĩ có lẽ bạn cũng muốn thử điều này:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
Các $IFS
bit chủ yếu là về $*
. Điều quan trọng là các ( subshell bit )
là cũng là kết quả của một sự mở rộng vỏ và như vậy để mở rộng các đối số vào một chuỗi Tôi sử dụng được phân tách "$*"
(không eval
"$@"
, bằng cách này, trừ khi bạn tất cả nhất định đang của args có thể được ghép không gian) . Dấu phân cách giữa các args "$*"
là byte đầu tiên $IFS
và do đó có thể nguy hiểm khi tiếp tục mà không chắc chắn giá trị của nó. Vì vậy, các chức năng tiết kiệm $IFS
, đặt nó vào một \n
ewline đủ lâu để set ... "$*"
vào "$3"
, unset
là nó, sau đó reset giá trị của nó nếu nó trước đây có một.
Đây là một bản demo nhỏ:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
Bạn thấy tôi đặt hai lệnh trong giá trị của $TIME
nó - bất kỳ số nào cũng được - thậm chí không có gì - nhưng hãy chắc chắn rằng nó được thoát và trích dẫn đúng - và các đối số cũng vậy _time()
. Tất cả chúng sẽ được nối vào một chuỗi lệnh khi chúng được thực thi - nhưng mỗi đối số có \n
ewline riêng và do đó chúng có thể được trải ra tương đối dễ dàng. Hoặc nếu không, bạn có thể gộp tất cả chúng lại thành một, nếu bạn thích và tách chúng ra trên \n
ewlines hoặc semi-colons hoặc what-have-you. Chỉ cần chắc chắn rằng một đối số duy nhất đại diện cho một lệnh bạn cảm thấy thoải mái khi đặt dòng riêng của nó trong một tập lệnh khi bạn gọi nó. \(
, ví dụ là tốt, miễn là cuối cùng nó được theo sau \)
. Về cơ bản là những thứ bình thường.
Khi eval
được cho ăn đoạn trích trên, nó trông giống như:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
Và, kết quả của nó trông giống như ...
ĐẦU RA
+++ echo any number of subshells
++ echo 'any number of subshells'
any number of subshells
++ command -V time
time is a shell keyword
++ hash time
bash: hash: time: not found
real 0m0.003s
user 0m0.000s
sys 0m0.000s
++ set +x
Các hash
lỗi chỉ ra rằng tôi không có một /usr/bin/time
cài đặt (bởi vì tôi không) và command
chúng ta hãy cho chúng tôi biết thời gian đó đang chạy. Trailing set +x
là một lệnh khác được thực thi sau time
(có thể) - điều quan trọng là phải cẩn thận với các lệnh đầu vào khi eval
ing bất cứ thứ gì.