2010-07-15 18 views
19

Trong chương trình C, tôi có thể viết argv [0] và tên mới hiển thị trong danh sách ps.Làm thế nào để thay đổi argv0 trong bash để lệnh xuất hiện với tên khác trong ps?

Tôi có thể làm điều này bằng cách nào?

+0

Bạn có nghĩa là bạn muốn chạy tập lệnh bash shell và có tên trong * ps * xuất hiện dưới dạng "bash" không? – Karmastan

+0

Nếu tôi viết một kịch bản có tên là 'foo.sh', nó xuất hiện trong _ps_ như foo.sh. Tôi muốn nó hiển thị như 'bar.sh'. – bstpierre

+0

btw tôi nghi ngờ bằng văn bản argv0 thực sự là hợp pháp, đặc biệt nếu những gì bạn viết dài hơn bản gốc, nhưng tôi cần tìm một tài liệu tham khảo cho số này – frankc

Trả lời

10

Tôi đã có cơ hội trải qua nguồn gốc cho bash và có vẻ như không có bất kỳ hỗ trợ nào để viết cho argv [0].

25

Bạn có thể làm điều đó khi chạy chương trình mới qua exec -a <newname>.

+1

+1: và để thêm vào ở trên, bạn có thể có một "nếu $ 0 không phải là những gì tôi muốn, sau đó 'exec -a what_i_want'" ở đầu ... – eruciform

+1

Dường như không có bất kỳ ảnh hưởng đến tôi trong Bash 4.0.33 –

+4

Thật không may nó không ảnh hưởng đến vỏ * hiện tại *. Bạn phải mở một cái mới bằng cách sử dụng nó. –

6
(exec -a foo bash -c 'echo $0') 
+0

Điều này sẽ * khởi động lại * quá trình. Không giống như viết cho argv [0] để thay đổi tên. – bstpierre

+1

Vâng, nó dồn một subshell, sau đó thay thế subshell đó bằng quá trình bắt đầu bởi 'exec'. Đó là gần giống với những gì sẽ xảy ra khi bạn chỉ cần gõ 'bash -c 'echo $ 0'' – chepner

0

Tôi sẽ chỉ thêm rằng điều này phải có thể trong thời gian chạy, ít nhất là trong một số môi trường. Gán $ 0 trong perl trên linux sẽ thay đổi những gì hiển thị trong ps. Tôi không biết làm thế nào mà được thực hiện, tuy nhiên. Nếu tôi có thể tìm ra, tôi sẽ cập nhật điều này.

chỉnh sửa: Dựa trên cách thức hoạt động của perl, nó không phải là nhỏ. Tôi nghi ngờ có bất kỳ bask được xây dựng theo cách trong thời gian chạy nhưng không biết chắc chắn. Bạn có thể xem how perl does sets the process name at runtime.

5

Tôi giả định rằng bạn đã có một kịch bản lệnh shell mà bạn muốn thực thi sao cho quy trình tập lệnh có một argv[0] mới. Ví dụ (tôi đã chỉ thử nghiệm này trong bash, vì vậy tôi đang sử dụng đó, nhưng điều này có thể làm việc ở nơi khác).

#!/bin/bash 

echo "process $$ here, first arg was $1" 
ps -p $$ 

Đầu ra sẽ là một cái gì đó như thế này:

$ ./script arg1 
process 70637 here, first arg was arg1 
    PID TTY   TIME CMD 
70637 ttys003 0:00.00 /bin/bash ./script arg1 

Vì vậy ps cho thấy vỏ, /bin/bash trong trường hợp này. Bây giờ hãy thử tương tác vỏ của bạn exec -a, nhưng trong một subshell do đó bạn không thổi đi những vỏ tương tác:

$ (exec -a MyScript ./script arg1) 
process 70936 here, first arg was arg1 
    PID TTY   TIME CMD 
70936 ttys008 0:00.00 /bin/bash /path/to/script arg1 

Woops, vẫn hiển thị /bin/bash. Chuyện gì đã xảy ra? Các exec -a có thể đã thiết lập argv[0], nhưng sau đó một trường hợp mới của bash bắt đầu bởi vì hệ điều hành đọc #!/bin/bash ở đầu tập lệnh của bạn. Ok, nếu chúng ta thực hiện việc thực hiện bên trong kịch bản thì sao? Đầu tiên, chúng ta cần một số cách để phát hiện xem đây có phải là "đầu tiên" thực thi kịch bản hay không, ví dụ thứ hai, exec ed, nếu không trường hợp thứ hai sẽ thực thi lại, và bật và lặp lại trong một vòng lặp vô hạn. Tiếp theo, chúng tôi cần tệp thực thi là không phải là là tệp có dòng #!/bin/bash ở trên cùng, để ngăn hệ điều hành thay đổi argv [0] mong muốn của chúng tôi. Đây là nỗ lực của tôi:

$ cat ./script 
#!/bin/bash 

__second_instance="__second_instance_$$" 
[[ -z ${!__second_instance} ]] && { 
    declare -x "__second_instance_$$=true" 
    exec -a MyScript "$SHELL" "$0" "[email protected]" 
} 

echo "process $$ here, first arg was $1" 
ps -p $$ 

Nhờ this answer, tôi thử nghiệm đầu tiên đối với các biến môi trường __second_instance_$$, dựa trên PID (mà không thay đổi qua exec) để nó sẽ không va chạm với các kịch bản khác sử dụng kỹ thuật này. Nếu nó trống, tôi giả định đây là trường hợp đầu tiên, và tôi xuất biến môi trường đó, sau đó exec. Nhưng, quan trọng, tôi không thực hiện kịch bản này, nhưng tôi thực thi trực tiếp nhị phân hệ vỏ, với đoạn mã này ($0) làm đối số, chuyển qua tất cả các đối số khác ([email protected]). Biến môi trường là một chút của một hack.

Bây giờ đầu ra là thế này:

$ ./script arg1 
process 71143 here, first arg was arg1 
    PID TTY   TIME CMD 
71143 ttys008 0:00.01 MyScript ./script arg1 

Đó là gần như ở đó.argv[0]MyScript như tôi muốn, nhưng có thêm arg ./script trong đó là hậu quả của việc thực hiện trực tiếp vỏ (thay vì thông qua quá trình xử lý #! của OS). Thật không may, tôi không biết làm thế nào để có được bất kỳ tốt hơn này.

9

Chỉ cần cho các hồ sơ, mặc dù nó không chính xác trả lời câu hỏi các poster ban đầu, đây là một cái gì đó tầm thường để làm với zsh:

ARGV0=emacs nethack 
0

Sao chép bash thực thi với một tên khác nhau.

Bạn có thể làm điều này trong kịch bản gốc ...

cp /bin/bash ./new-name 
PATH=$PATH:. 
exec new-name $0 

Nếu bạn đang cố gắng giả vờ bạn không phải là một kịch bản shell bạn có thể đổi tên kịch bản chính nó một cái gì đó mát mẻ hay thậm chí là "" (một đơn không gian) vì vậy

exec new-name " " 

Sẽ thực thi bash tập lệnh của bạn và xuất hiện trong danh sách ps như chỉ new-name.

OK để gọi một kịch bản "" là một ý tưởng rất xấu :)

Về cơ bản, để thay đổi tên

bash script 

đổi tên bash và đổi tên kịch bản.

Nếu bạn lo lắng, như ông McDoom. rõ ràng là, về việc sao chép nhị phân sang tên mới (hoàn toàn an toàn), bạn cũng có thể tạo liên kết tượng trưng

ln -s /bin/bash ./MyFunkyName 
./MyFunkyName 

Bằng cách này, liên kết tượng trưng xuất hiện trong danh sách ps. (một lần nữa sử dụng PATH = $ PATH :. nếu bạn không muốn ./)

+0

Tôi hy vọng không có người mới thấy nghĩa đen đổi tên bash và đổi tên kịch bản. Điều này tôi chắc chắn sẽ phá vỡ rất nhiều điều! – mcdoomington

+0

:) nó bắt đầu với "** Sao chép ** thực thi bash sang một tên khác." và các lệnh rõ ràng. Tôi làm điều này khá nhiều nếu tôi muốn một bin với một tên khác nhau, phá vỡ không có gì để thay đổi tên của một nhị phân, rõ ràng bạn cần phải để lại/bin/bash nó ở đâu. Đôi khi các thùng hoạt động khác nhau theo tên được sử dụng, nhưng chúng thường có hành vi mặc định. Tôi làm điều đó với bash rất nhiều kể từ khi tôi hack mã bash và biên dịch các phiên bản của riêng tôi. – teknopaul

+0

Hi Teknopaul, vâng (tôi đọc nó và hiểu), nhưng bạn biết cách sao chép và dán SO champs hoạt động - có lẽ chỉnh sửa câu trả lời để nói TẠI SAO bạn sao chép Bash sang tên khác;) Nếu ai đó thay đổi bash thực sự ...họ sẽ ở trong một chuyến đi nếu họ khởi động lại và không có lời nhắc. – mcdoomington

Các vấn đề liên quan