Xuất một biến có dấu chấm (.) Trong đó


38

Làm thế nào để xuất một biến có dấu chấm trong đó. Tôi nhận được 'tên biến không hợp lệ' khi tôi thử:

 export my.home=/tmp/someDir
-ksh: my.home=/tmp/someDir: invalid variable name

Ngay cả việc thoát metacharacter dot (.) Cũng không giúp được gì

$ export my\.home=/tmp/someDir
export: my.home=/tmp/someDir: is not an identifier


1
Thật không may, nó không được liệt kê khi tôi gõ / tìm kiếm câu hỏi tương tự. lấy làm tiếc. ..
dùng1587504

Câu trả lời:


49

Ít nhất là cho bashtrang man định nghĩa cú pháp xuất là:

export [-fn] [name[=word]] ...

Nó cũng định nghĩa một "tên" là:

   name   A  word  consisting  only  of alphanumeric characters and under
          scores, and beginning with an alphabetic character or an  under
          score.  Also referred to as an identifier.

Do đó bạn thực sự không thể định nghĩa một biến như my.homenó không phải là định danh hợp lệ.

Tôi rất chắc chắn ksh của bạn có định nghĩa rất giống với định danh và do đó cũng không cho phép loại biến này. (Hãy xem trang người đàn ông của nó.)

Tôi cũng rất chắc chắn có một số loại tiêu chuẩn chung (POSIX?) Chỉ định, những gì được phép làm định danh (và do đó là một tên biến).


Nếu bạn thực sự cần loại biến này vì một số lý do bạn có thể sử dụng một cái gì đó như

env "my.home=/tmp/someDir" bash

để định nghĩa nó nào. Nhưng sau đó, một lần nữa, bạn sẽ không thể truy cập nó bằng cú pháp shell thông thường. Trong trường hợp này, bạn có thể cần một ngôn ngữ khác như perl:

perl -e 'print $ENV{"my.home"}'

Ví dụ

env "my.home=/tmp/someDir" perl -le 'print $ENV{"my.home"}'

nên in đường dẫn của bạn.


Đó là vì sự hợp nhất của kiến. Và thật không may, nó không cho phép đặt / xuất biến từ unix. Chấp nhận câu trả lời của bạn. ..
dùng1587504

1
ant thường được cấu hình bởi một biến môi trường duy nhất được gọi là ANT_OPTShoặc bởi ~ / .antrc. Không cần tên biến môi trường lạ cho chính kiến.
michas

8

Trong khi các biến môi trường có thể có bất kỳ tên nào (bao gồm cả chuỗi rỗng) không chứa dấu bằng hoặc byte rỗng, shell biến các biến môi trường thành biến shell và trong hầu hết các shell, tên biến được giới hạn ở các ký tự chữ và số ASCII và _trong đó ký tự đầu tiên có thể ' t là một chữ số (trừ các tham số vị trí và những người đặc biệt khác như $*, $-, $@, ..., (mà không được ánh xạ tới các biến môi trường tương ứng)). Cũng lưu ý rằng một số biến được dành riêng / đặc biệt bởi / cho trình bao.

Ngoại lệ cho điều đó:

  • Các rcvỏ và các dẫn xuất của nó giống như esakangahỗ trợ bất kỳ tên ngoại trừ chuỗi rỗng, và những người được tất cả số hoặc chứa =ký tự (và luôn luôn xuất khẩu tất cả các biến của họ đối với môi trường, và hãy cẩn thận của các biến đặc biệt thích *, status, pid...):

    ; '%$£"' = test
    ; echo $'%$£"'
    test
    ; '' = x
    zero-length variable name
    ;
    

    Tuy nhiên, nó sử dụng mã hóa riêng cho các biến có tên không chứa alnums hoặc cho mảng khi được truyền trong môi trường của các lệnh đang được thực thi:

    $ rc -c '+ = zzz; __ = zzz; a = (zzz xxx); env' | sed -n /zzz/l
    __2b=zzz$
    __5f_=zzz$
    a=zzz\001xxx$
    $ env +=x rc -c "echo $'+'"
    x
    $ env __2b=x rc -c "echo $'+'"
    x
    
  • AT & T ksh, yashzsh(còn bashnhưng chỉ cho các ký tự single-byte) alnums hỗ trợ tại địa phương hiện nay, không chỉ những người ASCII.

    $ Stéphane=1
    $ echo "$Stéphane"
    1
    

    Trong các shell đó, bạn có thể thay đổi ngôn ngữ để coi hầu hết các ký tự là alpha, nhưng vẫn không hoạt động đối với các ký tự ASCII như thế nào .. Bạn có thể đánh lừa zshhoặc kshsuy nghĩ £là một chữ cái, nhưng không phải là .bất kỳ ký tự ASCII nào khác (trong đó việc cho phép các ký tự trong tên biến được quan tâm, không phải cho toàn [[:alpha:]]cầu chẳng hạn).

  • ksh93có các biến đặc biệt có tên chứa một dấu chấm ${.sh.version}, nhưng chúng không được ánh xạ tới các biến môi trường và đặc biệt. Điều .này là để đảm bảo nó không xung đột với các biến khác. Nếu nó đã quyết định gọi nó $sh_version, sau đó nó có thể có khả năng bị phá vỡ kịch bản sử dụng mà biến đã (xem ví dụ như thế nào zshcó vấn đề với nó $pathhay $commands(một csh la biến mảng / băm đặc biệt) mà phá vỡ một số kịch bản).

Lưu ý rằng ngoài việc vỏ không hỗ trợ các biến, một số vỏ như pdksh / mksh làm loại bỏ chúng ra khỏi môi trường mà họ nhận được ( bashloại bỏ một với một cái tên rỗng, ash, kshbashloại bỏ những chuỗi môi trường không chứa một =ký tự):

$ env %%%=test 1=%%% a.b=%%% mksh -c env | grep %%%
$ env %%%=test 1=%%% a.b=%%% bash -c env | grep %%%
%%%=test
a.b=%%%
1=%%%

$ perl -le '$ENV{""}="%%%"; exec "bash", "-c", "env"' | grep %%%
$ perl -le '$ENV{""}="%%%"; exec "zsh", "-c", "env"' | grep %%%
=%%%

$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/ash",a,e);}'|tcc -run - | grep %%%
$ echo 'main(){char*a[]={"sh","-c","env",0};char*e[]={"%%%",0};
    execve("/bin/zsh",a,e);}'|tcc -run - | grep %%%
%%%

Tóm lại, tốt nhất là gắn bó với tên biến được hỗ trợ bởi hầu hết vỏ và thậm chí cố gắng sử dụng chữ hoa cho các biến môi trường (và giảm trường hợp hoặc trường hợp hỗn hợp cho các biến shell không xuất) tránh những người là đặc biệt trong vỏ (như IFS, PS1, BASH_VERSION...).

Nếu bạn cần đặt một biến như vậy trong một vỏ không hỗ trợ chúng, nhưng không loại bỏ chúng, bạn có thể tự kiểm tra lại, với một cái gì đó như:

#! /bin/ksh -
perl -e 'exit 1 unless defined($ENV{"a.b"})' || exec env a.b=%%% "$0" "$@"

(rõ ràng, nếu bạn cần thực hiện nó ở giữa tập lệnh, điều đó sẽ không có ích, nhưng sau đó bạn có thể xem cách tiếp cận đó để lưu và khôi phục môi trường thực thi shell qua trình thực thi lại). Hoặc thử cách tiếp cận trình gỡ lỗi:

gdb --batch-silent -ex 'call putenv("a.b=%%%")' --pid="$$"

(mà ai có vẻ làm việc với zsh, yash, cshtcshtrên Linux amd64, nhưng không phải với bất kỳ vỏ khác tôi đã cố gắng ( mksh, ksh93, bash, dash)).


1
mksh(và pdksh) thực sự xây dựng các quy trình môi trường mà chúng sinh ra hoàn toàn từ đầu, chỉ sử dụng các tham số được xuất trong môi trường thực thi shell hiện tại, vì vậy không có cách nào để chuyển các biến đó qua các shell đó. (Lưu ý rằng các biến được thông qua có thể thay đổi; ví dụ: tôi dự định hỗ trợ xuất khẩu mảng trong mkshmột ngày nào đó.)
mirabilos

0

Như các bài viết khác chỉ ra, các shell phổ biến nhất không cho phép thiết lập các biến môi trường với các dấu chấm trong tên. Tuy nhiên, tôi đã tìm thấy các tình huống, đặc biệt liên quan đến Docker và các chương trình được gọi, trong đó phần mềm yêu cầu các giá trị chính có dấu chấm.

Tuy nhiên, trong mỗi tình huống này, các cặp giá trị khóa đó có thể được truyền cho chương trình thông qua các phương tiện khác ngoài các biến môi trường. Ví dụ: trong Ant, bạn có thể sử dụng "-propertyfile (tên tệp)" để chuyển vào tập tin thuộc tính được định dạng tập hợp các giá trị khóa. Confd cho phép "tập tin cuối cùng -file (tập tin yaml)".

Tôi đã chuyển các biến môi trường dưới dạng "C__any_value = 'my.property.key = giá trị'". Sau đó tôi đã chuyển lời gọi chương trình sang lần đầu tiên tạo tệp:

set | awk -- 'BEGIN { FS="'\''" } /^C__/ {print $2}' > my-key-values.txt

Các setlệnh, trong Borne Shell, ý chí sản lượng mỗi tài sản trên một dòng riêng biệt theo hình thức

C__any_value='my.property.key=the value'

Các awklệnh sẽ chỉ xử lý các biến môi trường bắt đầu với C__, sau đó trích xuất các giá trị chứa trong dấu nháy đơn.

Phương pháp này yêu cầu giá trị biến môi trường được đặt ở dạng chính xác mà chương trình xử lý yêu cầu. Ngoài ra, nếu giá trị thuộc tính hoặc khóa của bạn sẽ chứa các dấu ngoặc đơn, thì bạn sẽ cần thay đổi ký tự dấu tách trường awk thành ký tự mà bạn biết sẽ không xuất hiện và bao quanh giá trị với ký tự đó. Ví dụ: để sử dụng %làm dấu phân cách:

$ C__1="%my.key=the'value%"
$ set | awk -- 'BEGIN { FS="%" } /^C__/ {print $2}'
my.key=the'"'"'value

(đầu ra chính xác sẽ phụ thuộc vào vỏ của bạn.) Bạn sẽ cần thực hiện các bước bổ sung để giải mã trích dẫn thoát.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.