2013-07-01 33 views
42

cách bỏ đặt biến chỉ đọc trong Bash?Bỏ đặt biến chỉ đọc trong bash

$ readonly PI=3.14 

$ unset PI 
bash: PI: readonly variable 

hoặc không thể?

+0

ah http xấu của tôi : //tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_01.html Biến các biến chỉ đọc. Các biến này sau đó không thể được gán giá trị bởi các câu lệnh gán tiếp theo, cũng như không thể được đặt. – Kokizzu

+0

Thông thường các biến được đọc chỉ vì **/etc/profile ** chứa rất nhiều dòng như thế này 'readonly TMOUT'. Tôi thích để bình luận những dòng và để mở một kết nối mới với máy Linux đó. –

Trả lời

65

Trên thực tế, bạn có thể bỏ đặt một readonly biến. nhưng tôi phải cảnh báo rằng đây là một phương pháp hacky. Thêm câu trả lời này, chỉ như thông tin, không phải là đề xuất. Sử dụng có nguy cơ của riêng bạn. Thử nghiệm trên ubuntu 13.04, bash 4.2.45.

Phương pháp này liên quan đến việc biết một chút mã nguồn bash & được kế thừa từ câu trả lời this.

$ readonly PI=3.14 
$ unset PI 
-bash: unset: PI: cannot unset: readonly variable 
$ cat << EOF| sudo gdb 
attach $$ 
call unbind_variable("PI") 
detach 
EOF 
$ echo $PI 

$ 
+26

Bây giờ đó là những gì tôi gọi là lập trình bẻ khóa redneck;) – Floyd

+3

Lưu ý: Không bị cám dỗ để thay đổi 'cat << EOF | sudo gdb' đến 'sudo gdb << EOF'. Nó _may_ ** không ** làm việc, vì nhà cung cấp đầu vào được chuyển hướng - 'bash' đang bị dừng do tệp đính kèm' gdb'. – anishsane

+0

Tôi nghĩ câu trả lời [this] (http://stackoverflow.com/questions/17397069/unset-readonly-variable-in-bash#21294582) chính xác hơn một chút, vì nó không yêu cầu sudo và kết thúc gdb đúng – Rafareino

1

lệnh chỉ đọc làm cho nó cuối cùng và vĩnh viễn cho đến khi quá trình kết thúc chấm dứt. Nếu bạn cần thay đổi biến, đừng đánh dấu chỉ đọc.

2

Bạn có thể không, từ trang hướng dẫn của unset:

Đối với mỗi tên, loại bỏ các biến hoặc chức năng tương ứng. Nếu không có tùy chọn nào được cung cấp, hoặc tùy chọn -v được cho, mỗi tên là một biến hệ vỏ. Biến chỉ đọc có thể không được đặt. Nếu -f được chỉ định, mỗi tên đề cập đến hàm vỏ và định nghĩa hàm bị xóa. Mỗi biến hoặc hàm không được đặt sẽ bị xóa khỏi môi trường được truyền cho các lệnh tiếp theo. Nếu bất kỳ RANDOM, SECONDS, LINENO, HISTCMD, FUNCNAME, GROUPS hoặc DIRSTACK nào không được đặt, chúng sẽ mất các thuộc tính đặc biệt của chúng, ngay cả khi chúng được đặt lại sau đó. Trạng thái thoát là đúng trừ khi tên chỉ đọc.

+2

Những gì tôi không hiểu là lý do tại sao 'typeset + r VAR' không hoạt động kể từ đó, cũng theo trang người dùng,' Sử dụng '+' thay vì '-' sẽ tắt thuộc tính thay thế, với ngoại lệ là + a có thể không được sử dụng để phá hủy một biến mảng.' –

4

Theo man page:

unset [-fv] [name ...] 
      ... Read-only variables may not be 
      unset. ... 

Nếu bạn chưa xuất khẩu biến, bạn có thể sử dụng exec "[email protected]" để khởi động lại shell của bạn, tất nhiên bạn sẽ mất tất cả các biến un xuất khác cũng . Dường như nếu bạn bắt đầu một trình bao mới mà không có exec, nó sẽ mất thuộc tính chỉ đọc của nó cho trình bao đó.

3

Không, không phải trong trình bao hiện tại. Nếu bạn muốn gán một giá trị mới cho nó, bạn sẽ phải ngã ba một vỏ mới, nơi nó sẽ có một ý nghĩa mới và sẽ không được coi là read only.

$ { (readonly pi=3.14; echo $pi); pi=400; echo $pi; unset pi; echo [$pi]; } 
3.14 
400 
[] 
32

Tôi đã thử các gdb Hack ở trên vì tôi muốn bỏ đặt TMOUT (để vô hiệu hóa tính năng tự động logout), nhưng trên máy có TMOUT thiết lập như là chỉ đọc, tôi không được phép sử dụng sudo. Nhưng kể từ khi tôi sở hữu quá trình bash, tôi không cần sudo. Tuy nhiên, cú pháp không hoàn toàn phù hợp với máy tôi đang sử dụng.

này đã làm việc, mặc dù (tôi đặt nó trong tập tin .bashrc của tôi):

# Disable the stupid auto-logout 
unset TMOUT > /dev/null 2>&1 
if [ $? -ne 0 ]; then 
    gdb <<EOF > /dev/null 2>&1 
attach $$ 
call unbind_variable("TMOUT") 
detach 
quit 
EOF 
fi 
+3

Tôi khuyên bạn nên sử dụng các tùy chọn '-q -n' để tắt' gdb' không tải bất kỳ tệp _.gdbinit_ nào cho mỗi an toàn. –

+0

* "vì tôi sở hữu quy trình bash, tôi không cần sudo" * Lưu ý rằng điều này phụ thuộc vào hệ điều hành bạn đang sử dụng và cách cấu hình nó. [Với hầu hết các phiên bản hiện đang sử dụng của hạt nhân Linux] (https://www.kernel.org/doc/Documentation/security/Yama.txt) đây là [được điều khiển thông qua '/ proc/sys/kernel/yama/ptrace_scope'] (https://askubuntu.com/q/41629/22949). Các giá trị phổ biến nhất là '0', trong trường hợp này bạn có thể thực hiện điều này và' 1', trong trường hợp này bạn có thể không phải là 'gdb' không phải là cha mẹ trực tiếp của quá trình' bash' đang được sửa lỗi] (https://unix.stackexchange.com/a/403693/11938). –

+0

Mặc dù '-q' và' -n' hữu ích, chúng (cụ thể là '-q') không làm im lặng' gdb', vì vậy vẫn cần chuyển hướng '/ dev/null'. Mặc dù gợi ý tuyệt vời, @LucasCimon – fbicknel

0

Cụ WRT vào biến TMOUT. Một tùy chọn khác nếu gdb không có sẵn là sao chép bash vào thư mục chính của bạn và vá chuỗi TMOUT trong nhị phân thành một thứ khác, ví dụ XMOUX. Và sau đó chạy thêm lớp vỏ này và bạn sẽ không bị hết thời gian chờ.

+0

Thậm chí còn nhiều điều ác hơn là hack gdb. Vì vậy ... 1! –

0

Trong zsh,

$ typeset +r PI 

(Vâng, tôi biết câu hỏi nói bash. Nhưng khi bạn Google cho zsh, bạn cũng nhận được một loạt các câu hỏi bash.)

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