Невозможно передать символ «#» в качестве аргумента командной строки


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. Это читает #и останавливается там. Я не знаю почему, и я не могу найти ответ в моих копиях языка программирования C и 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 Вам нужно узнать, как работает оболочка. Это не имеет никакого отношения к вашему C-коду.
chepner

3
Ах, вы можете набирать комментарии в интерактивных сеансах оболочки, чтобы оболочка могла сразу игнорировать их после того, как вы закончили печатать. Какая полезная особенность.
Joker_vD

6
@Joker_vD Хотя вы рассматриваете оболочку как интерфейс командной строки, на самом деле это интерпретатор сценариев. Тот факт, что вы можете использовать его как интерактивный CLI, является приятным бонусом. Почему интерпретируемое поведение должно значительно отличаться, когда вы «запускаете скрипт», а не вводить команды в интерактивном режиме? Что о echo echo Hello, World | bash. Это интерактивно? Или может быть bash <<END?
Кристофер Шульц

6
@Joker_vD: я часто печатаю комментарии в интерактивных сессиях, чтобы вернуться к ним в истории моей оболочки. Иногда это делается для записи хэша коммита или другого идентификатора, отправленного на стандартный вывод; иногда нужно отметить, что команда потерпела неудачу как примечание к моему будущему я; иногда это для записи временных данных для специального тестирования. Это является полезной функцией.
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.