Các -c
tùy chọn cho phép các chương trình để các lệnh chạy. Dễ dàng hơn nhiều để rẽ nhánh và làm
execl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);
hơn là để rẽ nhánh, tạo đường ống, ngã ba lần nữa, gọi execl
từng đứa trẻ, gọi wait
, kiểm tra trạng thái thoát, ngã ba lần nữa, gọi close(1)
, mở tệp, đảm bảo rằng nó được mở trên mô tả tệp 1 và thực hiện một thao tác khác execl
. Tôi tin rằng đây là lý do tại sao tùy chọn được tạo ngay từ đầu.
Hàm system()
thư viện chạy một lệnh theo phương thức trên.
- Nó cung cấp một cách để nhận một lệnh phức tạp tùy ý và làm cho nó trông giống như một lệnh đơn giản. Điều này hữu ích với các chương trình chạy lệnh do người dùng chỉ định, chẳng hạn như
find … -exec
hoặc xargs
. Nhưng bạn đã biết điều đó; đó là một phần của câu trả lời cho câu hỏi của bạn,
Làm thế nào để xác định một lệnh ghép làm đối số cho một lệnh khác?
Nó có thể có ích nếu bạn đang chạy một vỏ tương tác khác ngoài bash. Ngược lại, nếu bạn đang chạy bash, bạn có thể sử dụng cú pháp này
$ tro -c " lệnh "
︙
$ csh -c " lệnh "
︙
$ dash -c " lệnh "
︙
$ zsh -c " lệnh "
︙
để chạy một lệnh trong shell khác, vì tất cả các shell đó cũng nhận ra -c
tùy chọn. Tất nhiên bạn có thể đạt được kết quả tương tự với
$ trolệnh
tro $
︙
tro $ thoát
$ cshlệnh
csh $
︙
csh $ thoát
$ gạch nganglệnh
dash $
︙
dấu gạch ngang $ exit
$ zshlệnh
zsh $
︙
thoát zsh $
Tôi đã sử dụng ash$
, vv, để minh họa các lời nhắc từ các shell khác nhau; bạn có thể sẽ không thực sự có được những thứ đó.
Nó có thể có ích nếu bạn muốn chạy một lệnh trong shell bash tươi tươi của Tep; ví dụ,
$ ls -lA
total 0
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1
-rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2
$ echo *
file2
$ shopt -s dotglob
$ echo *
.file1 file2
$ bash -c "echo *"
file2
hoặc là
$ type shift
shift is a shell builtin
$ alias shift=date
$ type shift
shift is aliased to ‘date’
$ bash -c "type shift"
shift is a shell builtin
Trên đây là một đơn giản hóa quá mức sai lệch. Khi bash được chạy với -c
, nó được coi là một vỏ không tương tác và nó không đọc ~/.bashrc
, trừ khi được -i
chỉ định. Vì thế,
$ loại cp
cp được đặt bí danh là 'cp -i' # Được xác định trong ~ / .bashrc
$ cp .file1 file2
cp: ghi đè 'file2'? n
$ bash -c "cp .file1 file2"
# Tập tin hiện tại bị ghi đè mà không cần xác nhận!
$ bash -c -i "cp .file1 file2"
cp: ghi đè 'file2'? n
Bạn có thể sử dụng -ci
, -i -c
hoặc -ic
thay vì -c -i
.
Điều này có thể áp dụng ở một mức độ nào đó cho các shell khác được đề cập trong đoạn 3, do đó, dạng dài (nghĩa là dạng thứ hai, thực sự chính xác cùng một lượng gõ) có thể an toàn hơn, đặc biệt là nếu bạn đã thiết lập các tệp cấu hình / khởi tạo cho những cái vỏ.
Như Wildcard đã giải thích , vì bạn đang chạy một cây quy trình mới (một quy trình shell mới và, có khả năng, quá trình con của nó), các thay đổi đối với môi trường được tạo trong lớp con
có thể ảnh hưởng đến shell cha (thư mục hiện tại, các giá trị của môi trường các biến, định nghĩa hàm, v.v.) Vì vậy, thật khó để tưởng tượng một lệnh dựng sẵn shell sẽ hữu ích khi chạy bởi sh -c
.
fg
, bg
và jobs
không thể ảnh hưởng hoặc truy cập các công việc nền được bắt đầu bởi shell cha, cũng không thể wait
chờ chúng.
về cơ bản tương đương với việc chỉ chạy theo cách thông thường, trực tiếp từ vỏ tương tác.
là một sự lãng phí lớn thời gian
vàsh -c "exec some_program"
some_program
sh -c exit
ulimit
umask
có thể thay đổi cài đặt hệ thống cho quy trình con và sau đó thoát mà không thực hiện chúng.
Chỉ về lệnh dựng sẵn duy nhất có chức năng trong sh -c
ngữ cảnh là kill
. Tất nhiên, các lệnh mà chỉ có sản phẩm đầu ra ( echo
, printf
, pwd
và type
) không bị ảnh hưởng, và nếu bạn viết một tập tin, mà sẽ kéo dài.
- Tất nhiên bạn có thể sử dụng một dựng sẵn kết hợp với
một lệnh bên ngoài; ví dụ,
sh -c "cd some_directory ; some_program "
nhưng về cơ bản bạn có thể đạt được hiệu ứng tương tự với một lớp con bình thường:
(cd some_directory ; some_program )
cái nào hiệu quả hơn Giống nhau (cả hai phần) có thể được nói cho một cái gì đó như
sh -c "umask 77; some_program "
hoặc ulimit
(hoặc shopt
). Và vì bạn có thể đặt một lệnh phức tạp tùy ý sau -c
- cho đến mức độ phức tạp của tập lệnh shell đầy đủ - bạn có thể có cơ hội sử dụng bất kỳ tiết mục nào của nội dung; ví dụ source
, read
, export
, times
, set
và unset
vv
echo printf type pwd
là nội dung; vì vậy nhữngset shopt shift read readarray mapfile trap declare/typeset export local let readonly unset
thứ này không ảnh hưởng đến cha mẹ nhưng vẫn có thể hữu ích trong một phức tạp vừa phải-c
.