Kịch bản Bash gọi một chương trình có một số dấu sao trong các đối số


0

Tôi đã dành hàng giờ trước để cố gắng viết một kịch bản bash khá đơn giản và tôi chưa bao giờ cảm thấy ngu ngốc như vậy.

Vì vậy, tôi có một danh sách các chuỗi (là các đặc tả bộ chọn gói cho trình quản lý gói, nếu có vấn đề) có thể chứa dấu hoa thị. Tôi cần xây dựng một dòng lệnh bảo quản các dấu sao đó và sau đó gọi một chương trình. Đây là nỗ lực ngây thơ của tôi:

xs="foo/bar */*"

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

Tôi cần echo gọi để tương đương với

echo   -0 foo/bar    -0 '*/*' 

đầu ra nào -0 foo/bar -0 */*.

P. S. Trong thực tế, dòng đầu tiên phức tạp hơn một chút: xs="$some foo/bar */* $(get_others)".


Nếu bạn chạy tập lệnh này trong một thư mục chứa a/b, bạn sẽ nhận được -0 foo/bar -0 a/b thay thế.

Khi tôi thay đổi dòng cuối cùng thành

echo "$xs_cmd"  # note the quotes

tôi có -0 foo/bar -0 a/b và, trước hết, đó là những gì tôi không muốn echo với một Độc thân và hơn nữa điều đó cho tôi biết rằng việc mở rộng đang diễn ra sớm hơn, có khả năng trong for vòng lặp.

Nhưng tôi có thể thay đổi for dòng vì

for x in "$xs"; do  # note the quotes

sẽ chỉ thực hiện vòng lặp chỉ một lần: -0 foo/bar */* (có một -0 ) vì vậy thêm các trích dẫn đó không phải là một lựa chọn chắc chắn

Bây giờ nếu tôi trở lại tập lệnh gốc và thay thế dòng đầu tiên bằng

xs="foo/bar '*/*'"  # note additional single quotes

tôi có -0 foo/bar -0 '*/*' (trích dẫn duy nhất nên có ở đó).

Có vẻ như tôi đã thử mọi sự kết hợp của dấu ngoặc kép và dấu gạch chéo ngược của dấu sao và tôi thực sự không biết phải làm gì bây giờ.

Câu trả lời:


0

Tôi đã sử dụng tập lệnh gốc của bạn, nhưng với dấu ngoặc đơn ở dòng đầu tiên (chỉ) và nó hoạt động như tôi nghĩ bạn muốn nó -0 trước mỗi đường dẫn tệp): -

xs='foo/bar */*'

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

Bạn có thể sẽ gặp vấn đề khi bạn sử dụng nó nếu có các khoảng trống được nhúng trong bất kỳ đường dẫn tệp nào. Nếu vậy thay đổi lệnh trong vòng lặp thành: -

  xs_cmd="$xs_cmd  -0 \"$x\" "

Errr, không, điều này vẫn thực hiện mở rộng trong for vòng lặp và đầu ra a/b thay vì */*. Một vấn đề khác là dòng đầu tiên có phần phức tạp hơn trong thực tế; Tôi sẽ cập nhật câu hỏi trong một phút.
kirelagin

Tôi nghĩ bạn muốn nó mở rộng trong for vòng lặp. Tôi đã thử nghiệm nó trên Ubuntu 14.04 và nhận được -0 "foo/bar" -0 "dir/file" -0 "dir/file" ...
AFH

Bạn có thể muốn đọc lại câu hỏi của tôi, đặc biệt là phần ngay trước thước kẻ ngang cho đầu ra mong muốn: Không mở rộng nên được thực hiện; Tôi cần tất cả các dấu sao còn lại tại chỗ.
kirelagin

ĐƯỢC. Tôi đã tìm thấy một cái gì đó hoạt động. Tạo dòng đầu tiên của bạn xs="foo/bar @/@", sau đó của bạn for vòng lặp thêm dòng xs_cmd=$(echo $xs_cmd|sed "s/@/\*/g"). Nếu bạn không thể tìm thấy một nhân vật như @ mà không có trong bất kỳ tên tập tin của bạn, sau đó sử dụng xs="foo/bar ///"xs_cmd=$(echo $xs_cmd|sed "s-///-\*/\*-g"). Tôi đề nghị sử dụng @ đầu tiên vì nó dễ dàng hơn để khái quát hóa cho các chuỗi khác với dấu hoa thị.
AFH

Vì vậy, bây giờ tôi có xs_cmd đó là một chuỗi với một số dấu sao. Làm thế nào để tôi chuyển nó vào lệnh ( echo trong ví dụ của tôi)? echo $xs_cmd sẽ thực hiện mở rộng. echo "$xs_cmd" sẽ gọi echo với một đối số duy nhất.
kirelagin

0

Tùy thuộc vào những gì bạn đang cố gắng để đạt được, bạn cần phải trích dẫn những điều này */*:

xs="foo/bar '*/*'" #!

xs_cmd=""
for x in $xs ; do
    xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"

hoặc sử dụng mảng hoặc cả hai:

xs=("foo/bar" "*/*") #!

xs_cmd=""
for x in "${xs[@]}"; do
    xs_cmd="$xs_cmd  -0 '$x' " #!
done

echo "$xs_cmd"
eval "echo $xs_cmd"

Như đã đề cập trong câu hỏi của tôi, đề xuất đầu tiên của bạn dẫn đến kết quả đầu ra sau: -0 foo/bar -0 '*/*', có nghĩa là các trích dẫn được truyền theo chương trình. Đề xuất thứ hai của bạn cho kết quả -0 'foo/bar' -0 'a/b' cả hai chuyển báo giá cho chương trình thực hiện mở rộng, trong khi tôi không cần.
kirelagin
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.