bash: Một số vấn đề khi sử dụng đọc <<< Hồi $ VARIABLE 'trên phân vùng gốc chỉ đọc. Bất kỳ giải pháp được biết đến?


11

Chỉ bằng sự trùng hợp, tôi đã phải sử dụng tập lệnh ATA-ID-to-device-name (tìm thấy ở đây: /server/244944/linux-ata-errors-translating-to-a-device-name/ 426561 # 426561 ) trên phân vùng chỉ đọc / . Trong trường hợp bạn tò mò, đó là một bàn điều khiển phục hồi Ubuntu sẽ cho phép bạn truy cập vào /phân vùng của mình , nhưng sẽ gắn kết nó chỉ đọc theo mặc định. Tôi rất vui vì điều đó, bởi vì nếu không tôi có lẽ sẽ không bao giờ phát hiện ra rằng kịch bản của tôi hoạt động kỳ lạ trên hệ thống R / O do một dòng cụ thể, điều này:

IFS=: read HostMain HostMid HostSub <<< "$HostFull"

Điều này không hoạt động nếu không có quyền viết. Tôi sẽ không nghĩ rằng nó sẽ thất bại, mặc dù. Nhưng rõ ràng là <<<nhà điều hành không yêu cầu ghi một số tập tin tạm thời vào một nơi nào đó.

Nhưng có cách nào để tránh việc tạo một tập tin tạm thời, hoặc, có cách nào để xác định nơi tập tin được ghi vào không? Trong bảng điều khiển phục hồi Ubuntu, có --- đủ kỳ lạ --- ghi quyền trên /runthư mục, vì vậy điều đó sẽ làm, nếu tôi có thể "bảo" bằng cách nào đó readđể ghi tệp tạm thời vào một nơi khác hơn bình thường.


2
@gniourf_gniourf Không, việc mở một bộ mô tả tập tin sẽ không thành vấn đề (tại sao lại như vậy?), và /dev/fdkhông liên quan gì đến việc này. <<<là thủ phạm, bởi vì nó tạo ra một tập tin tạm thời (cần phải được viết ở đâu đó).
Gilles 'SO- ngừng trở nên xấu xa'

Câu trả lời:


8

Một mảng có thể làm cho phân tích chuỗi mà không cần tệp tạm thời. Đừng quên tắt Globing.

set -f
IFS=: Hosts=($HostFull)
HostMain=${Hosts[0]}
HostMid=${Hosts[1]}
HostSub=${Hosts[2]}
set +f

2
hoặc thậm chí không có IFS, nếu bạn chắc chắn không có khoảng trắng nào $HostFullnhư vậy : Hosts=( ${HostFull//:/ } ). Hoặc thậm chí nếu có khoảng trắng: HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}(hoặc một cái gì đó tương tự, tôi đang bị lẫn lộn :D).
gniourf_gniourf

Bạn đã đúng, khi bạn hiển thị mở rộng tham số là các giao dịch phức tạp ...
xae

4

Tôi đồng ý với @gniourf_gniourf, có lẽ bạn cần quyền truy cập ghi nhưng không phải với các mô tả tệp, rất có thể là một tệp.

Bạn có thể kiểm tra điều này bằng cách theo dõi việc thực hiện lệnh của bạn khi ở trong phân vùng chỉ đọc.

{ strace -p "$$" & sleep 1; read var1 <<< "hi"; sleep 1; kill "$1"; }

Ở trên sẽ chạy stracetrên shell Bash (quá trình $$). Sau đó nó ngủ trong 1 giây và sau đó chạy readtừ ĐÂY. Tôi đã đặt chuỗi "hi"ở vị trí này. Sau đó tôi sleeptrong một giây và sau đó killcác strace.

Thí dụ

Trong khi phân tích cú pháp đầu ra này, bạn sẽ nhận thấy rằng một tệp được mở dưới dạng O_WRONLY, đó là để ghi vào một tệp.

open("/tmp/sh-thd-4137571604", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3

Ở trên chúng ta có thể thấy tập tin nào được ghi theo chuỗi lệnh của bạn.


1
Không phải để tạo ra các mô tả tập tin, (điều đó không có ý nghĩa gì). Để tạo tập tin . Nó không phải readlà mở một tập tin để viết (đó sẽ là ngớ ngẩn), đó là <<<.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles - cảm ơn, tôi không hiểu những gì nó nói với tôi.
Dọn dẹp

Cảm ơn rât nhiều! Một kỹ thuật rất hay, thậm chí có thể giúp tôi nhiều lần trong tương lai với các vấn đề tương tự. Tuy nhiên, có một điều lo lắng cho tôi, và đó là một thực tế mà /tmplà một hardcoded con đường. Và có lẽ bạn đã đoán ra, /tmp IS đã có rồi, nhưng chỉ đọc thôi! Và vì làm việc trên bảng điều khiển phục hồi đó sẽ cho tôi đăng nhập vào hệ thống tệp trực tiếp của mình , tôi sẽ không muốn gây rối ở đó bằng cách liên kết tượng trưng hoặc bất cứ điều gì (ngay cả trong khi trong bảng điều khiển đó).
cú pháp

3

Tôi thấy các tham số vị trí rất hữu ích cho loại nhiệm vụ này. Nó thường có thể mang theo cho tất cả các vỏ, và chi phí không có dĩa cũng như các tệp tạm thời.

$ HostFull=main:mid:sub    
$ oldIFS=$IFS; IFS=:; set -- $HostFull; IFS=$oldIFS
$ echo $1
main
$ echo $2
mid
$ echo $3
sub

Một cách tiếp cận tốt! Cảm ơn bạn. Thêm vào đó, tôi thích nó rằng nó không yêu cầu bất kỳ công cụ bên ngoài nào (mà chúng ta thường không được mong đợi tìm thấy trong những môi trường bị hạn chế đó). Điều duy nhất mà có thể gây ra một số rắc rối là $1, $2, $3thứ: hãy nhớ rằng trong một kịch bản, điều này thường sẽ đại diện cho một cuộc tranh cãi thông qua với kịch bản riêng của mình . - Và trong khi chúng ta đang ở đó: nếu IFS có nghĩa là một khoảng trắng, * IFS = * sẽ không thực hiện theo cú pháp này; bạn sẽ phải xác định rõ ràng IFS = '' .
cú pháp
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.