Cygwin mất ký tự ổ đĩa của đường dẫn kiểu Windows trong các biến


1

Tôi gặp phải một vấn đề có vẻ lạ khi cố gắng lấy tập lệnh xây dựng (từ bên thứ 3) để làm việc với thiết lập của mình với Win7 và Cygwin (phiên bản mới nhất). Vấn đề có thể được mô tả tốt nhất với bashđoạn mã ví dụ :

foo="/cygdrive/c/svn/Projects/Client Config/Android/Repack/foo/out"
cygpath -w "$foo/play-services-tasks/classes.jar"
bar=`cygpath -w "$foo/play-services-tasks/classes.jar"`
echo $bar

Chạy kết quả như sau (chú ý đến dấu hai chấm sau ký tự ổ đĩa):

C:\svn\Projects\Client Config\Android\Repack\foo\out\play-services-tasks\classes.jar
C \svn\Projects\Client Config\Android\Repack\foo\out\play-services-tasks\classes.jar

Vì vậy, đường dẫn (đầu ra của cygpath) là thích hợp trước khi đặt nó vào một biến, nhưng biến không còn chứa dấu hai chấm sau ký tự ổ đĩa. Điều đó, đến lượt nó, làm cho một kịch bản / công cụ khác thất bại khi nó cố gắng lặp lại trên các đường dẫn được phân tách bằng dấu cách trong một biến. Và thật không may, công cụ đó hy vọng sẽ có các đường dẫn kiểu Windows.

Không cần phải nói, tôi đang bối rối ...

Vấn đề xuất hiện khi tập lệnh xây dựng thay đổi và nó có thể thiếu một số hack tương thích cygwin, một số trong đó tôi đã quản lý để áp dụng, nhưng điều này thực sự khó chịu. Có thể có thể làm việc xung quanh các bộ phận đã thay đổi bằng cách nào đó nhưng tôi muốn tìm hiểu lý do cho việc tìm kiếm của tôi và cách giải quyết vấn đề đó trực tiếp.

Câu trả lời:


1

Vấn đề xuất hiện khi tập lệnh xây dựng thay đổi và nó thiếu một số hack tương thích cygwin, một số trong đó tôi đã quản lý để áp dụng trước khi nhấn vào tập lệnh này.

Cuối cùng tôi cũng tìm ra được thủ phạm thực sự, đó là có một hàm trong tập lệnh xây dựng (trong khi lặp qua PATHbiến) đặt biến môi trường IFS=:và sau đó không đặt lại nó. Khi bashsử dụng biến đó để phân tách các chuỗi thành các trường và nó cũng mở rộng biến khi sử dụng các biến không được trích dẫn. Vì vậy, việc khắc phục là phải thực hiện SAVEIFS="$IFS"trước khi cài đặt lại IFSvà sau đó đặt lại IFS=$SAVEIFS. Ngoài ra, như Gordon Davisson vui lòng giải thích, tôi có thể đảm bảo rằng các biến được sử dụng luôn được trích dẫn kép (ví dụ echo "$bar"thay vì echo $bar).

Vấn đề được giải quyết, không thực sự liên quan đến Cygwin theo bất kỳ cách nào khác ngoài dấu hai chấm được sử dụng cho các mục đích khác nhau trong Windows và Cygwin và do đó đôi khi cần phải chạm vào biến phân tách trường bên trong. Vì lý do duy nhất đó, tôi nghĩ rằng tôi nên để nó ở đây, trong trường hợp người khác gặp phải một vấn đề tương tự. Ngoài ra còn có rất nhiều công cụ tốt trên tất cả các khía cạnh của việc mở rộng vỏ trên USE.


thử thanh = $ (cygpath -w "$ foo / play-services-task /
class.jar

Nó không xảy ra khi biến được gán, nhưng khi nó được sử dụng. Khi lớp vỏ mở rộng một biến mà không cần hai dấu ngoặc kép (ví dụ echo $bar), giá trị được chia thành "chữ" dựa trên IFS(và sau đó bất kỳ "chữ" có chứa ký tự đại diện được mở rộng đến một danh sách phù hợp với tên tập tin. Thiết IFStrở lại bình thường là tốt ý tưởng, nhưng bạn cũng nên trích dẫn hai tham chiếu biến (ví dụ echo "$bar") để ngăn phân tích cú pháp bất ngờ như thế này.
Gordon Davisson

Mở rộng biến Shell là và không phải là lĩnh vực kiến ​​thức mạnh nhất của tôi, phải thừa nhận điều đó, nhưng thật tốt khi học ... @GordonDavisson biến sau đó được sử dụng để "tách" eval set -- $bar, tôi tự hỏi liệu có cách nào để ngăn chặn Vỏ từ mở rộng mọi thứ với điều đó?
zagrimsan

@zagrimsan Đừng sử dụng eval, đó là một nam châm lỗi thực sự trừ khi bạn biết chính xác những gì bạn đang làm. Sẽ không set -- "$bar"làm việc trong trường hợp này? (Và sau đó hãy chắc chắn tham chiếu đối số bằng dấu ngoặc kép, như trong "$1".)
Gordon Davisson

Chà, kịch bản xây dựng không phải là sáng tạo của tôi ... Nhưng ngay cả với IFS=:nó dường như việc sử dụng dấu ngoặc kép ở mọi nơi, tức là eval set -- "$dxlibs"; echo "$@";sẽ ngăn chặn sự mở rộng xảy ra. Cảm ơn, tôi sẽ cố nhớ điều này vào lần tới khi tôi gặp phải chuyện như thế này (và nhớ đừng gây ra điều này trong các kịch bản của riêng tôi).
zagrimsan
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.