2010-11-04 2 views
11

Trong tập lệnh của tôi, tôi muốn có thể ghi vào một tập tin hoặc để xuất bản dựa trên một số điều kiện nhất định. Tôi tò mò là tại sao điều này không làm việc trong kịch bản của tôi:Chuyển hướng Bash với bộ mô tả tập tin hoặc tên tập tin trong biến

out=\&1 
echo "bird" 1>$out 

tôi đã cố gắng kết hợp khác nhau của dấu ngoặc kép, nhưng tôi tiếp tục có một "& 1" tập tin được tạo ra thay vì nó bằng văn bản cho stdout. Tôi có thể làm gì để có được điều này để làm việc như thế nào tôi muốn?

+0

Hệ thống của bạn có hỗ trợ out =/dev/stdout không? – mob

Trả lời

1

Tôi chắc chắn nó phải làm theo thứ tự trong đó bash xử lý dòng lệnh. Các công trình sau đây:

export out=\&1 
eval "echo bird 1>${out}" 

vì biến thay xảy ra trước đánh giá.

0

Hãy thử với eval. Nó sẽ làm việc bằng cách giải thích giá trị của bản thân $out:

out='&1' 
eval "echo \"bird\" 1>$out" 

Sẽ in bird trên đầu ra tiêu chuẩn (và vào một tập tin nếu bạn thay đổi out).

Lưu ý rằng bạn phải cẩn thận với những gì nằm trong chuỗi eval. Lưu ý dấu gạch chéo ngược với dấu ngoặc kép nội bộ và biến số $out bị biến đổi (bằng dấu ngoặc kép) trước khi thực hiện eval.

5

Một lựa chọn có thể an toàn hơn để eval là dup đích của bạn vào một bộ mô tả tập tin tạm thời sử dụng exec (file descriptor 3 trong ví dụ này):

if somecondition; then exec 3> destfile; else exec 3>&1; fi 

echo bird >&3 
+0

+1, Tốt nhất là tránh 'eval'. –

+3

@ Dennis: Tôi thực sự không thể hiểu rằng eval cliché ... Có vẻ như được điền tất cả các câu hỏi bash liên quan trong stackoverflow :) Một lần nữa và lần thứ ngàn: 'eval' là một công cụ và không phải là một nguy cơ của chính nó .. Nó giống như nói rằng bạn phải tránh Lisp bởi vì bạn có thể xem xét dữ liệu Lisp như mã ... –

+1

@Diego: 'eval' có thể là một công cụ hữu ích. Nó cũng trình bày những rủi ro an ninh tiềm ẩn nghiêm trọng. Nếu bạn tránh nó, bạn không phải lo lắng về những rủi ro cụ thể đó. Nó thường dễ dàng để tránh. Đi theo con đường dễ dàng và an toàn bất cứ khi nào có thể. Khi bạn sử dụng 'eval', hãy đảm bảo rằng bạn thực sự cần nó và bạn đã khử trùng đúng cách đầu vào và thực hiện các bước cần thiết khác để ngăn chặn sự cố. Xem [BashFAQ/048] (http://mywiki.wooledge.org/BashFAQ/048) và [câu hỏi SO tuyệt vời] (http://stackoverflow.com/q/2571401) (cho và chống lại). Ngoài ra, lưu ý rằng tôi đã nói "tốt nhất để tránh" không "không bao giờ sử dụng". –

2

expounding về câu trả lời của Diego. Để thay đổi vị trí đặt giá trị có điều kiện

if [ someCondition ] ; then 
    # all output now goes to $file 
    exec 1>$file 
fi 

echo "bird" 

Hoặc tạo trình mô tả tệp của riêng bạn;

if [ someCondition ] ; then 
    # 3 points to stdout 
    exec 3>&1 
else 
    # 3 points to a file 
    exec 3>$outfile 
fi 

echo "bird" >&3 

Chuyển thể từ: csh programming considered harmful - hãy kiểm tra để tìm thêm một số thủ thuật chuyển hướng. Hoặc đọc trang bash man.

+0

Tôi đã gặp sự cố khi làm việc này trong tập lệnh của riêng mình, tôi sẽ phải sử dụng ký hiệu mở rộng đầy đủ cho một số lý do, ví dụ:' destfile = "/ some/path"; exec 3> $ {destfile} ' – Eliot

2

Đến năm 2015, bạn có thể chuyển hướng đến >&${out}. Ví dụ:

exec {out}>&1 
echo "bird" 1>&${out}