Làm thế nào để tạo một biến từ một lớp con có sẵn trong vỏ cha


11

Tôi đã viết một kịch bản nhanh và bẩn để xử lý một số báo cáo từ một dịch vụ web:

BASE_URL='http://example.com/json/webservice/'
FIRST=1
FINAL=10000

for report_code in $(seq 1 $FINAL); do
  (time -p response=$(curl --write-out %{http_code} --silent -O ${BASE_URL}/${report_code}) ) 2> ${report_code}.time

  echo $response  # <------- this is out of scope!  How do I fix that?
  if [[ $response = '404' ]]; then
    echo "Deleting report # ${report_code}!"
    rm ${report_code}
  else
    echo "${report_code} seems to be good!"
  fi
done

Tôi cần phải bọc timelệnh trong một lớp con để tôi có thể chuyển hướng đầu ra của nó, nhưng điều đó làm cho giá trị $responsekhông có sẵn cho shell cha. Làm thế nào để tôi có được xung quanh vấn đề này?

Câu trả lời:


11

Bạn không thể mang giá trị của một biến từ một nhánh con đến cha mẹ của nó, không phải không thực hiện một số giao tiếp dễ bị lỗi và rườm rà.

May mắn thay, bạn không cần một subshell ở đây. Chuyển hướng chỉ yêu cầu nhóm lệnh với { … }, không phải là một nhánh con.

{ time -p response=$(curl --write-out '%{http_code}' --silent -O "${BASE_URL}/${report_code}"); } 2> "${report_code}.time"

(Đừng quên dấu ngoặc kép xung quanh các thay thế .)


thật buồn cười khi mọi ngôn ngữ lập trình đều có thể làm được điều đó. tôi đã dành 1h để làm việc mà không có giải pháp khả thi nào. tôi thất vọng.
Tới Kra

1
@ToKra Không. Không có ngôn ngữ lập trình có thể làm điều này. (Hầu như) bất kỳ ngôn ngữ lập trình nào cũng có thể mang lại giá trị của biến từ chương trình con hoặc khối lệnh cho cha mẹ của nó và đó chính xác là những gì tôi giải thích trong câu trả lời của mình: sử dụng nhóm lệnh { … }thay vì nhóm con ( … ).
Gilles 'SO- ngừng trở nên xấu xa'

4

Người dùng U & L: Trước khi bỏ qua câu trả lời của tôi về việc sử dụng kiểu C với main()chức năng, vui lòng truy cập liên kết này: https://unix.stackexchange.com/a/313561/85039 Sử dụng các chức năng chính trong tập lệnh là một cách phổ biến, được sử dụng bởi nhiều chuyên gia trên đồng ruộng.


Như Gilles đã chỉ ra, các lớp con không thể tạo ra các biến có sẵn bên ngoài môi trường của chúng. Nhưng hãy tiếp cận vấn đề này từ một góc độ khác - nếu bạn viết tập lệnh của mình trong các hàm, có thể khai báo biến localvà có thể chỉnh sửa.

Từ hướng dẫn sử dụng bash 4.3, localmô tả:

... Khi cục bộ được sử dụng trong một hàm, nó làm cho tên biến có phạm vi hiển thị bị giới hạn ở hàm đó và các phần tử con của nó ...

Thí dụ:

#!/bin/bash

outter()
{
    for i in $(seq 1 3)
    do
        var=$i
    done
}

main()
{
    local var=0
    outter
    echo $var
}
main "$@"
$ ./testscript.sh                                                                                                        
3

Như bạn có thể thấy sau 3 lần lặp của hàm lặp, biến được sửa đổi.


Hmm, hành vi không trực quan cho lập trình viên C. Tôi thường mong outtermuốn đề cập đến một ví dụ toàn cầu var.
Ruslan

Câu trả lời này có một số sai sót. "$var"không cần thiết trong cuộc gọi ra outter. Nó không làm gì cả. Và cũng local var=0không làm gì cả; ouf cuộc gọi outtersẽ ghi đè var, như bạn đã nói.
Gole Ramblar

@GolarRamblar Tôi đã xóa "$var"như là đối số vị trí outter; để công bằng, đây là một thói quen. Bạn có thể xây dựng như local var=0 một phần?
Sergiy Kolodyazhnyy
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.