Không thể chuyển ký tự '#' làm đối số dòng lệnh


36

Tôi không thể vượt qua các chuỗi bắt đầu bằng #các đối số dòng lệnh.

Đây là một bài kiểm tra đơn giản:

#include <stdio.h>

int main(int argc, char *argv[])
{
    for (int i = 1; i < argc; i++)
        printf("%s ", argv[i]);

    putchar('\n');

    return 0;
}

Nếu tôi nhập các đối số như sau:

2 4 # 5 6

Giá trị của argc3và không 6. Nó đọc #và dừng ở đó. Tôi không biết tại sao và tôi không thể tìm thấy câu trả lời trong các bản sao Ngôn ngữ lập trình CC Primer Plus của mình .


44
cú pháp tô sáng trên StackOverflow minh họa vấn đề của bạn độc đáo :)
Brad Allred

Câu trả lời:


47

#bắt đầu một nhận xét trong shell Unix, giống như //trong C.

Điều này có nghĩa là khi shell chuyển các đối số cho progam, nó sẽ bỏ qua mọi thứ theo sau #. Thoát khỏi nó bằng dấu gạch chéo ngược hoặc dấu ngoặc kép sẽ có nghĩa là nó được xử lý như các tham số khác và chương trình sẽ hoạt động như mong đợi.

2 4 \# 5 6

hoặc là

2 4 '#' 5 6

hoặc là

2 4 "#" 5 6

Lưu ý rằng #ký tự chỉ là một ký tự khi bắt đầu một từ, vì vậy điều này cũng sẽ hoạt động:

2 4#5 6

2
Đây có vẻ là một danh sách khá tốt unix.stackexchange.com/a/270979
fanduin

22
@ cd-00 Bạn cần tìm hiểu cách thức hoạt động của vỏ. Điều này không có gì để làm với mã C của bạn.
chepner

3
À, vì vậy bạn có thể nhập nhận xét trong các phiên shell tương tác , vì vậy shell có thể bỏ qua ngay lập tức sau khi bạn nhập xong. Thật là một tính năng hữu ích.
Joker_vD

6
@Joker_vD Trong khi bạn nghĩ về shell như một giao diện dòng lệnh, thì nó thực sự là một trình thông dịch kịch bản. Thực tế là bạn có thể sử dụng nó như một CLI tương tác là một phần thưởng tuyệt vời. Tại sao người diễn giải nên cư xử khác biệt đáng kể khi bạn đang "chạy tập lệnh" so với việc gõ các lệnh trong tương tác? Những gì về echo echo Hello, World | bash. Là tương tác? Hoặc có thể bash <<END?
Christopher Schultz

6
@Joker_vD: Tôi thường xuyên nhập nhận xét trong các phiên tương tác để tham khảo lại trong lịch sử trình bao của mình. Đôi khi, điều này là để ghi lại một hàm băm cam kết hoặc ID khác được phát ra trên thiết bị xuất chuẩn; đôi khi cần lưu ý rằng một lệnh thất bại như một ghi chú cho bản thân tương lai của tôi; đôi khi nó để ghi dữ liệu thời gian cho điểm chuẩn ad hoc. Nó một tính năng hữu ích.
wchargein

12

Khi chuyển giá trị qua các đối số dòng lệnh, bạn phải thực hiện theo các hướng dẫn sau. Các ký tự sau có ý nghĩa đặc biệt đối với chính vỏ trong một số ngữ cảnh và có thể cần phải thoát trong các đối số:

` Backtick (U+0060 Grave Accent)
~ Tilde (U+007E)
! Exclamation mark (U+0021)
# Hash (U+0023 Number Sign)
$ Dollar sign (U+0024)
& Ampersand (U+0026)
* Asterisk (U+002A)
( Left Parenthesis (U+0028)
) Right parenthesis (U+0029)
 (⇥) Tab (U+0009)
{ Left brace (U+007B Left Curly Bracket)
[ Left square bracket (U+005B)
| Vertical bar (U+007C Vertical Line)
\ Backslash (U+005C Reverse Solidus)
; Semicolon (U+003B)
' Single quote / Apostrophe (U+0027)
" Double quote (U+0022)
↩ New line (U+000A)
< Less than (U+003C)
> Greater than (U+003E)
? Question mark (U+003F)
  Space (U+0020)1

3
Làm thế nào họ nên được trốn thoát sau đó?
ilkkachu

3
\ - Đã thoát bằng cách sử dụng dấu gạch chéo ngược .EX:2 4 \{#,$,&,*} 5 6
VJAYSLN

8

Đó là bởi vì bạn đang sử dụng một shvỏ giống như. Trích dẫn #hoặc thoát nó bằng cách sử dụng \và nó sẽ làm việc.

Điều này được gọi là một nhận xét trong sh. Nó làm cho #(dấu cách-băm) và bất kỳ đối số nào sau đó bị loại bỏ. Nó được sử dụng tương tự như các bình luận trong C, nơi nó được sử dụng để viết mã tài liệu.

Các chuỗi bắt đầu bằng $được gọi là các biến trong sh. Nếu bạn chưa đặt biến, nó sẽ mở rộng thành một chuỗi trống.

Ví dụ: tất cả những điều này sẽ là những cách hợp lệ để chuyển #ứng dụng của bạn:

2 4 '#' 5 6
2 4 "#" 5 6
2 4 \# 5 6

Và đây sẽ là những cách hợp lệ để vượt qua một chuỗi bắt đầu bằng $:

2 4 '$var' 5 6
2 4 '$'var 5 6
2 4 \$var 5 6

Xin lưu ý rằng các biến trong "s vẫn được mở rộng.

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.