Sự cố này là riêng đối với MinGW / MSYS thường được sử dụng như một phần của gói Git dành cho Windows .
Giải pháp là chuyển -subj
đối số với hàng đầu //
(dấu gạch chéo kép về phía trước) và sau đó sử dụng \
(dấu gạch chéo ngược) để phân tách các cặp khóa / giá trị. Như thế này:
"//O=Org\CN=Name"
Điều này sau đó sẽ được chuyển đến một cách kỳ diệu openssl
ở dạng mong đợi:
"/O=Org/CN=Name"
Vì vậy, để trả lời câu hỏi cụ thể, bạn nên thay đổi -subj
dòng trong script của mình thành dòng sau.
-subj "//C=GB\ST=someplace\L=Provo\O=Achme\CN=${FQDN}"
Đó phải là tất cả những gì bạn cần.
Phép thuật này là gì?
Đối với những người tò mò về chính xác những gì đang diễn ra ở đây, tôi có thể giải thích bí ẩn này. Lý do là MSYS giả định một cách hợp lý rằng các đối số chứa dấu gạch chéo thực sự là đường dẫn. Và khi những đối số đó được chuyển đến một tệp thực thi chưa được biên dịch riêng cho MSYS (như openssl
trong trường hợp này) thì nó sẽ chuyển đổi đường dẫn POSIX thành đường dẫn Win32 . Các quy tắc cho việc chuyển đổi này khá phức tạp vì MSYS cố gắng hết sức để giải quyết hầu hết các tình huống phổ biến về khả năng tương tác. Điều này cũng giải thích tại sao việc sử dụng openssl
từ dấu nhắc lệnh windows ( cmd.exe
) hoạt động tốt, vì không có chuyển đổi ma thuật nào được thực hiện.
Bạn có thể thử nghiệm chuyển đổi như thế này.
$ cmd //c echo "/CN=Name"
"C:/Program Files (x86)/Git/CN=Name"
Chúng tôi không thể sử dụng echo
tệp thực thi đi kèm với MSYS vì nó được biên dịch cho MSYS, thay vào đó chúng tôi sẽ sử dụng echo
nội trang trong cmd
. Lưu ý rằng vì cmd
công tắc bắt đầu bằng /
(phổ biến đối với các lệnh windows) nên chúng ta cần xử lý điều đó bằng dấu gạch chéo kép. Như chúng ta có thể thấy trong đầu ra, đối số đã được mở rộng thành đường dẫn cửa sổ và nó trở nên rõ ràng tại sao openssl
thực sự khẳng định điều đó Subject does not start with '/'.
.
Hãy xem thêm một số chuyển đổi.
$ cmd //c echo "//CN=Name"
/CN=Name
Dấu gạch chéo kép khiến MSYS tin rằng đối số là một chuyển đổi kiểu cửa sổ dẫn đến việc loại bỏ một /
chỉ (không có chuyển đổi đường dẫn). Bạn sẽ nghĩ rằng với điều này, chúng tôi chỉ có thể sử dụng dấu gạch chéo để thêm nhiều cặp khóa / giá trị hơn. Hãy thử điều đó.
$ cmd //c echo "//O=Org/CN=Name"
//O=Org/CN=Name
Đột nhiên, dấu gạch chéo đôi khi bắt đầu không được gỡ bỏ. Điều này là do bây giờ, với dấu gạch chéo sau dấu gạch chéo kép ban đầu, MSYS nghĩ rằng chúng ta đang tham chiếu đến một đường dẫn UNC (ví dụ: // server / path). Nếu điều này được chuyển cho openssl
nó sẽ bỏ qua câu nói khóa / giá trị đầu tiên Subject Attribute /O has no known NID, skipped
.
Đây là quy tắc liên quan từ wiki MinGW giải thích hành vi này:
- Một đối số bắt đầu bằng 2 trở lên / được coi là một chuyển đổi kiểu Windows đã thoát và sẽ được chuyển với phần đầu / loại bỏ và tất cả \ được thay đổi thành /.
- Ngoại trừ việc nếu có một / theo sau khối đứng đầu của /, thì đối số được coi là một đường dẫn UNC và khối đứng đầu / không bị loại bỏ.
Trong quy tắc này, chúng ta có thể thấy phương pháp chúng ta có thể sử dụng để tạo đối số mà chúng ta muốn. Vì tất cả những \
gì theo sau trong một đối số bắt đầu bằng //
sẽ được chuyển thành đơn giản /
. Hãy thử điều đó.
$ cmd //c echo "//O=Org\CN=Name"
/O=Org/CN=Name
Và như chúng ta có thể thấy nó hoạt động.
Hy vọng điều này làm sáng tỏ điều kỳ diệu một chút.
cat -vet /path/to/script
và xem các dòng kết thúc bằng '^ M $' (kiểu Windows) hay chỉ bằng '$' (kiểu unix).