Nie można przekazać znaku „#” jako argumentu wiersza polecenia

36

Nie mogę przekazać ciągów zaczynających się #od argumentów wiersza poleceń.

Oto prosty test:

#include <stdio.h>

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

    putchar('\n');

    return 0;
}

Jeśli wprowadzę argumenty w następujący sposób:

2 4 # 5 6

Wartość argcjest 3i nie 6. Tam czyta #i zatrzymuje się. Nie wiem dlaczego i nie mogę znaleźć odpowiedzi w moich kopiach The C Programming Language i C Primer Plus .

cd-00
źródło
44
podświetlanie składni na StackOverflow dobrze ilustruje twój problem :)
Brad Allred,

Odpowiedzi:

47

#zaczyna komentarz w powłokach uniksowych, podobnie jak //w C.

Oznacza to, że gdy powłoka przekazuje argumenty do progamu, ignoruje wszystko po znaku #. Ucieczka od ukośnika odwrotnego lub cudzysłowu oznacza, że ​​jest traktowany jak inne parametry, a program powinien działać zgodnie z oczekiwaniami.

2 4 \# 5 6

lub

2 4 '#' 5 6

lub

2 4 "#" 5 6

Pamiętaj, że #jest to znak komentarza tylko na początku słowa, więc powinno to również działać:

2 4#5 6
fanduin
źródło
2
To wydaje się być całkiem niezłą listą unix.stackexchange.com/a/270979
fanduin
22
@ cd-00 Musisz nauczyć się, jak działa powłoka. To nie ma nic wspólnego z twoim kodem C.
chepner
3
Ach, więc możesz wpisywać komentarze w interaktywnych sesjach powłoki, aby powłoka mogła ją zignorować natychmiast po zakończeniu pisania. Co za przydatna funkcja.
Joker_vD,
6
@Joker_vD Chociaż myślisz o powłoce jako interfejsie wiersza poleceń, tak naprawdę jest to interpreter skryptów. Fakt, że można go używać jako interaktywnego interfejsu CLI, jest miłym dodatkiem. Dlaczego interpretowany powinien zachowywać się zupełnie inaczej, gdy „uruchamiasz skrypt”, a nie wpisywać poleceń interaktywnie? Co echo echo Hello, World | bash. Czy to jest interaktywne? A może bash <<END?
Christopher Schultz
6
@Joker_vD: Często piszę komentarze w interaktywnych sesjach, aby odwoływać się do nich w mojej historii powłoki. Czasami ma to na celu zarejestrowanie skrótu zatwierdzenia lub innego identyfikatora emitowanego na standardowe wyjście; czasami trzeba zauważyć, że polecenie nie powiodło się jako notatka dla mojego przyszłego ja; czasami ma to na celu rejestrowanie danych czasowych do testów porównawczych ad hoc. Jest to przydatna funkcja.
wchargin
12

Podczas przekazywania wartości za pomocą argumentów wiersza poleceń należy wykonać następujące instrukcje. Następujące znaki mają specjalne znaczenie dla samej powłoki w niektórych kontekstach i może wymagać zmiany znaczenia w argumentach:

` 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
VJAYSLN
źródło
3
Jak więc powinni oni uciec?
ilkkachu
3
\ - Ucieczka za pomocą ukośnika odwrotnego .EX:2 4 \{#,$,&,*} 5 6
VJAYSLN
8

To dlatego, że używasz shpodobnej do powłoki. Cytuj #lub użyj \go, a będzie działać.

To się nazywa komentarz w sh. Powoduje #to odrzucenie (skrótu spacji) i wszelkich argumentów po nim. Jest używany podobnie jak komentarze w C, gdzie służy do dokumentowania kodu.

Ciągi rozpoczynające się od $są nazywane zmiennymi w sh. Jeśli nie ustawiłeś zmiennej, zostanie ona rozwinięta do pustego ciągu.

Na przykład wszystkie te sposoby byłyby prawidłowe do przekazania #aplikacji:

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

I byłyby to prawidłowe sposoby przekazywania ciągu zaczynającego się od $:

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

Pamiętaj, że zmienne wewnątrz "s są nadal rozwinięte.

SS Anne
źródło