Неможливо передати символ "#" як аргумент командного рядка


36

Я не можу передавати рядки, починаючи з #аргументів командного рядка.

Ось простий тест:

#include <stdio.h>

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

    putchar('\n');

    return 0;
}

Якщо я введіть аргументи так:

2 4 # 5 6

Значення argcє 3і ні 6. Він читає #і там зупиняється. Я не знаю чому, і я не можу знайти відповідь у своїх копіях The C Programming Language та C Primer Plus .


44
підсвічування синтаксису на StackOverflow чудово ілюструє вашу проблему :)
Бред Олред

Відповіді:


47

#починає коментар в оболонках Unix, подібно //до C.

Це означає, що коли оболонка передає аргументи прогам, вона ігнорує все, що слідує за #. Якщо уникнути його з косою рисою або котируваннями, це означає, що до нього поводяться як з іншими параметрами, і програма повинна працювати так, як очікувалося.

2 4 \# 5 6

або

2 4 '#' 5 6

або

2 4 "#" 5 6

Зауважте, що #символ коментаря є лише на початку слова, тому це також має працювати:

2 4#5 6

2
Здається, це досить хороший список unix.stackexchange.com/a/270979
fanduin

22
@ cd-00 Вам потрібно дізнатися, як працює оболонка. Це не має нічого спільного з вашим кодом С.
чепнер

3
Так, ви можете вводити коментарі в інтерактивних сесіях оболонок, щоб оболонка могла ігнорувати її негайно після того, як ви закінчили її вводити. Яка корисна особливість.
Joker_vD

6
@Joker_vD Хоча ви думаєте про оболонку як інтерфейс командного рядка, це насправді інтерпретатор сценарію. Те, що ви можете використовувати його як інтерактивний CLI, є приємним бонусом. Чому інтерпретовані повинні поводитися істотно по-іншому, коли ви "запускаєте сценарій" проти введення команд в інтерактивному режимі? Про що echo echo Hello, World | bash. Це інтерактивне? А може bash <<END?
Крістофер Шульц

6
@Joker_vD: Я часто набираю коментарі в інтерактивних сесіях, щоб посилатися на свою історію оболонок. Іноді це для запису хеш-коміту чи іншого ідентифікатора, випромінованого в stdout; іноді варто зазначити, що команда не вдалася як замітка до мого майбутнього «я»; іноді це записувати дані про терміни для спеціального тестування. Це є корисною функцією.
wchargin

12

При передачі значення через аргументи командного рядка вам необхідно пройти наступні інструкції. Наступні символи мають особливе значення для самої оболонки в деяких контекстах і, можливо, їх потрібно буде уникати в аргументах:

` 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
Як тоді їм уникнути?
ilkkachu

3
\ - Утекли за допомогою зворотної косої риски .EX:2 4 \{#,$,&,*} 5 6
VJAYSLN

8

Це тому, що ви використовуєте sh подібну оболонку. Цитуйте #або уникніть його, використовуючи, \і воно спрацює.

Це називається а коментарем у sh. Це призводить #до відмови (пробілу) та будь-яких аргументів після нього. Він використовується аналогічно коментарям у C, де він використовується для документування коду.

Струни, що починаються з $ , називаються змінними в sh. Якщо ви не встановили змінну, вона розшириться до порожнього рядка.

Наприклад, усе це було б дійсним способом передачі #вашої заявки:

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

І це дійсні способи передавання рядка, починаючи з $:

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

Зауважте, що змінні всередині "s все ще розширені.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.