skorupa C

skorupa C
Oryginalni autorzy Billa Joy'a
Pierwsze wydanie 1978 ; 45 lat temu ( 1978 )
Wersja stabilna
6.20.00 / 24 listopada 2016 ; 6 lat temu ( 2016-11-24 )
Magazyn
Napisane w C
System operacyjny BSD , UNIX , Linux , macOS
Typ powłoka Uniksa
Licencja Licencja BSD
Powłoka C działająca w usługach Windows dla systemu UNIX

Powłoka C ( csh lub ulepszona wersja, tcsh ) to powłoka systemu Unix stworzona przez Billa Joya , gdy był on doktorantem na Uniwersytecie Kalifornijskim w Berkeley pod koniec lat siedemdziesiątych. Był szeroko rozpowszechniany, począwszy od wydania 2BSD Berkeley Software Distribution (BSD), które Joy po raz pierwszy rozprowadził w 1978 roku. Innymi wczesnymi współtwórcami pomysłów lub kodu byli Michael Ubell, Eric Allman , Mike O'Brien i Jim Kulp.

Powłoka C to procesor poleceń , który zwykle jest uruchamiany w oknie tekstowym, umożliwiając użytkownikowi wpisywanie i wykonywanie poleceń. Powłoka C może również odczytywać polecenia z pliku, zwanego skryptem . Podobnie jak wszystkie powłoki Uniksa, obsługuje wieloznaczne nazwy plików , potoki , tutaj dokumenty , podstawianie poleceń , zmienne i struktury kontrolne do testowania warunków i iteracji . Tym, co odróżniało powłokę C od innych, zwłaszcza w latach 80., były jej interaktywne funkcje i ogólny styl. Jego nowe funkcje sprawiły, że korzystanie z niego było łatwiejsze i szybsze. Ogólny styl języka bardziej przypominał C i był postrzegany jako bardziej czytelny.

W wielu systemach, takich jak macOS i Red Hat Linux , csh to tak naprawdę tcsh , ulepszona wersja csh. Często jeden z tych dwóch plików jest dowiązaniem twardym lub dowiązaniem symbolicznym do drugiego, tak więc każda nazwa odnosi się do tej samej ulepszonej wersji powłoki C. Oryginalny kod źródłowy i plik binarny csh są częścią NetBSD .

W Debianie i niektórych pochodnych (w tym Ubuntu ) istnieją dwa różne pakiety: csh i tcsh. Pierwsza jest oparta na oryginalnej wersji csh z BSD, a druga to ulepszona wersja tcsh.

tcsh dodał nazwy plików i uzupełnianie poleceń oraz koncepcje edycji wiersza poleceń zapożyczone z systemu Tenex , który jest źródłem „t”. Ponieważ tylko dodawał funkcjonalność i nie zmieniał tego, co już istniało, tcsh pozostał wstecznie kompatybilny z oryginalną powłoką C. Chociaż zaczęło się jako gałąź boczna z oryginalnego drzewa źródłowego, które stworzyła Joy, tcsh jest teraz główną gałęzią ciągłego rozwoju. tcsh jest bardzo stabilny, ale nowe wydania nadal pojawiają się mniej więcej raz w roku i składają się głównie z drobnych poprawek błędów.

Cele projektowe i funkcje

Głównym celem projektu powłoki C było to, aby bardziej przypominała język programowania C i była lepsza do użytku interaktywnego.

Bardziej jak C

System Unix został napisany prawie wyłącznie w C, więc pierwszym celem powłoki C był język poleceń, który byłby bardziej spójny stylistycznie z resztą systemu. Słowa kluczowe, użycie nawiasów i wbudowana gramatyka wyrażeń powłoki C oraz obsługa tablic były pod silnym wpływem języka C.

Według dzisiejszych standardów, powłoka C może nie wydawać się bardziej podobna do C niż wiele innych popularnych języków skryptowych. Jednak w latach 80. i 90. różnica była uderzająca, szczególnie w porównaniu z powłoką Bourne'a (znaną również jako sh ), dominującą wówczas powłoką napisaną przez Stephena Bourne'a z Bell Labs . Ten przykład ilustruje bardziej konwencjonalne operatory wyrażeń i składnię powłoki C.

Skorupa Bourne'a


   

    #!/bin/sh  if  [  $days  -gt  365  ]  then  echo  To już ponad rok.  fi 

skorupa C


   
    #!/bin/csh  if  (  $days  > 365  )  then  echo  To ponad rok.  endif 

W języku Bourne'a brakowało gramatyki wyrażeń . Warunki w nawiasach kwadratowych musiały zostać ocenione przez wolniejszy sposób uruchamiania zewnętrznego testowego . Polecenie if polecenia sh potraktowało słowa argumentu jako nowe polecenie do uruchomienia jako proces potomny . Jeśli dziecko zakończyło pracę z kodem powrotu zerowym , sh szukałby klauzuli then (oddzielnej instrukcji, ale często pisanej połączonej w tym samym wierszu ze średnikiem) i uruchamia ten zagnieżdżony blok. W przeciwnym razie uruchomiłby plik else. Twarde linkowanie programu testowego jako „ test ” i „ [ ” dało notacyjną przewagę nawiasów kwadratowych i sprawiało wrażenie, że funkcjonalność testu jest częścią języka sh. użycie przez sh odwróconego słowa kluczowego do oznaczenia końca bloku sterującego było stylem zapożyczonym z ALGOL 68 .

Natomiast csh mógł bezpośrednio ocenić wyrażenie, co przyspieszyło działanie. Zapewniał również lepszą czytelność: jego wyrażenia wykorzystywały gramatykę i zestaw operatorów w większości skopiowanych z C, żadne z jego słów kluczowych nie zostało odwrócone, a ogólny styl był również bardziej podobny do C.

Oto drugi przykład, porównujący skrypty, które obliczają pierwsze 10 potęg liczby 2.

Skorupa Bourne'a




   

       
     
   
 #!/bin/sh  i  =  2  j  =  1  while  [  $j  -le  10  ]  wykonaj  echo  '2 **'  $j  =  $i  i  =  `  wyrażenie  $i  '*'  2  `  j  =  `  wyrażenie  $j  +  1  `  gotowe 

skorupa C


    
        #!/bin/csh  ustaw  i  =  2  ustaw  j  =  1  while  (  $j  <  =  10  )  echo  '2 **'  $j  =  $i  @ i *  =  2 @ j++  end 

Ponownie, z powodu braku gramatyki wyrażeń, skrypt sh używa podstawiania poleceń i polecenia expr . (Nowoczesna powłoka POSIX ma taką gramatykę: instrukcja może być napisana i=$((i * 2)) lub : "$((i *= 2))" .)

Na koniec trzeci przykład pokazujący różne style instrukcji switch .

Skorupa Bourne'a



         
   
 #!/bin/sh  dla  i  w  d*  czy  przypadek  $i  w  d?  )  echo  $i  jest krótkie  ;;  *  )  echo  $i  jest długie  ;;  gotowe  _ 

skorupa C



      
       
 
 #!/bin/csh  foreach  i  (  d*  )  switch  (  $i  )  case  d?:  echo  $i  to krótkie  przerwyw  default  :  echo  $i  to długie  końcew  koniec 

W skrypcie sh „ ;; ” oznacza koniec każdego przypadku, ponieważ w przeciwnym razie sh nie dopuszcza instrukcji null.

Ulepszenia do użytku interaktywnego

Drugim celem było to, aby powłoka C była lepsza do użytku interaktywnego. Wprowadził wiele nowych funkcji, które uczyniły go łatwiejszym, szybszym i bardziej przyjaznym w użyciu poprzez wpisywanie poleceń na terminalu. Użytkownicy mogli wykonywać zadania za pomocą znacznie mniejszej liczby naciśnięć klawiszy i działać szybciej. Najważniejszymi z tych nowych funkcji były mechanizmy historii i edycji, aliasy, stosy katalogów, notacja tyldy, cdpath, kontrola zadań i mieszanie ścieżek. Te nowe funkcje okazały się bardzo popularne, a wiele z nich zostało od tego czasu skopiowanych przez inne powłoki systemu Unix.

Historia

Historia pozwala użytkownikom przywołać poprzednie polecenia i ponownie je uruchomić, wpisując tylko kilka szybkich naciśnięć klawiszy. Na przykład wpisanie dwóch wykrzykników („ !! ”) jako polecenia powoduje wykonanie polecenia bezpośrednio poprzedzającego. Inne krótkie kombinacje klawiszy, np. „ !$ ” (oznaczające „ostatni argument poprzedniego polecenia”), umożliwiają wklejanie fragmentów poprzednich poleceń i edytowanie ich w celu utworzenia nowego polecenia.

Edycja operatorów

Edycji można dokonać nie tylko na tekście poprzedniego polecenia, ale także na podstawieniach zmiennych. Operatory obejmują zarówno proste wyszukiwanie/zastępowanie ciągów, jak i analizowanie nazwy ścieżki w celu wyodrębnienia określonego segmentu.

Skróty

Aliasy pozwalają użytkownikowi wpisać nazwę aliasu, a powłoka C rozszerzy ją wewnętrznie na dowolny zestaw słów zdefiniowany przez użytkownika. W wielu prostych sytuacjach aliasy działają szybciej i są wygodniejsze niż skrypty.

Stos katalogów

Stos katalogów umożliwia użytkownikowi wypychanie lub otwieranie bieżącego katalogu roboczego , co ułatwia przeskakiwanie między różnymi miejscami w systemie plików.

Notacja tyldy

Notacja tyldy oferuje skrócony sposób określania nazw ścieżek względem katalogu domowego za pomocą znaku „ ~ ”.

Uzupełnianie nazw plików

Klawisz Escape może być używany interaktywnie, aby pokazać możliwe uzupełnienia nazwy pliku na końcu bieżącego wiersza poleceń.

Ścieżka CD

Cdpath rozszerza pojęcie ścieżki wyszukiwania do komendy cd (zmień katalog): Jeśli określony katalog nie znajduje się w bieżącym katalogu , csh spróbuje go znaleźć w katalogach cdpath.

Kontrola pracy

Jeszcze w latach 80. większość użytkowników miała tylko proste terminale w trybie znakowym, które wykluczały wiele okien, więc mogli pracować tylko nad jednym zadaniem na raz. Sterowanie zadaniem powłoki C pozwoliło użytkownikowi zawiesić bieżącą czynność i utworzyć nową instancję powłoki C, zwaną zadaniem, przez wpisanie ^Z . Użytkownik może następnie przełączać się między zadaniami za pomocą fg . Aktywna praca miała być na pierwszym planie. Mówiono, że inne zadania były zawieszone (zatrzymane) lub działały w tle .

Haszowanie ścieżki

Haszowanie ścieżki przyspiesza wyszukiwanie plików wykonywalnych przez powłokę C. Zamiast wykonywać wywołania systemu plików w każdym katalogu ścieżki, pojedynczo, dopóki nie znajdzie pliku lub nie skończą mu się możliwości, powłoka C konsultuje się z wewnętrzną tablicą skrótów zbudowaną przez skanowanie katalogów ścieżek . Ta tabela może zwykle powiedzieć powłoce C, gdzie znaleźć plik (jeśli istnieje) bez konieczności wyszukiwania i można ją odświeżyć za pomocą rehash .

Przegląd języka

Powłoka C obsługuje jedną linię na raz. Każdy wiersz jest podzielony na tokeny na zestaw słów oddzielonych spacjami lub innymi znakami o specjalnym znaczeniu, w tym nawiasy, potoki i operatory przekierowania wejścia/wyjścia, średniki i ampersandy.

Podstawowe stwierdzenia

Podstawowa instrukcja to taka, która po prostu uruchamia polecenie. Pierwsze słowo jest traktowane jako nazwa polecenia do wykonania i może być poleceniem wewnętrznym, np. echo lub poleceniem zewnętrznym. Reszta słów jest przekazywana jako argumenty do polecenia.

Oto niektóre cechy gramatyki na poziomie instrukcji podstawowych:

Dzikie karty

Powłoka C, podobnie jak wszystkie powłoki uniksowe, traktuje każdy argument wiersza poleceń, który zawiera symbole wieloznaczne, jako wzorzec i zastępuje go listą wszystkich pasujących nazw plików (patrz globalizacja ) .

  • * pasuje do dowolnej liczby znaków.
  • ? pasuje do dowolnego pojedynczego znaku.
  • [ ... ] pasuje do dowolnego znaku w nawiasach kwadratowych. Dozwolone są zakresy przy użyciu łącznika.
  • [^ ... ] dopasowuje dowolny znak spoza zestawu.

Powłoka C wprowadziła również kilka udogodnień związanych z notacją (czasami nazywanych rozszerzonym globowaniem ), ponieważ została skopiowana przez inne powłoki systemu Unix.

wiele symboli wieloznacznych na poziomie katalogu, np. " */*.c ".

Od wersji 6.17.01 rekurencyjne symbole wieloznaczne à la zsh (np. " **/*.c " lub " ***/*.html ") są również obsługiwane z opcją globstar .

Powierzenie powłoce odpowiedzialności za interpretację symboli wieloznacznych było ważną decyzją w systemie Unix. Oznaczało to, że symbole wieloznaczne będą działać z każdym poleceniem i zawsze w ten sam sposób. Jednak decyzja opierała się na zdolności systemu Unix do wydajnego przekazywania długich list argumentów przez exec , którego csh używa do wykonywania poleceń. Natomiast w systemie Windows interpretacja symboli wieloznacznych jest konwencjonalnie wykonywana przez każdą aplikację. Jest to dziedzictwo MS-DOS, które pozwalało na przekazanie do aplikacji tylko 128-bajtowego wiersza poleceń, przez co stosowanie symboli wieloznacznych w wierszu polecenia DOS było niepraktyczne. Chociaż nowoczesny system Windows może przekazywać wiersze poleceń o długości do około 32 000 znaków Unicode , ciężar interpretacji symboli wieloznacznych pozostaje po stronie aplikacji.

przekierowanie we/wy

Domyślnie, gdy csh uruchamia polecenie, polecenie dziedziczy uchwyty plików stdio csh dla stdin , stdout i stderr , które normalnie wszystkie wskazują na okno konsoli , w którym działa powłoka C. Operatory przekierowania wejścia/wyjścia umożliwiają poleceniu użycie pliku zamiast wejścia lub wyjścia.

  • > file oznacza, że ​​stdout zostanie zapisane do pliku , nadpisując go, jeśli istnieje, i tworząc go, jeśli nie istnieje. Błędy nadal pojawiają się w oknie powłoki.
  • >& file oznacza, że ​​zarówno stdout, jak i stderr zostaną zapisane do file , nadpisując je, jeśli istnieje, i tworząc, jeśli nie.
  • >> plik oznacza, że ​​standardowe wyjście zostanie dodane na końcu pliku .
  • >>& plik oznacza, że ​​zarówno stdout, jak i stderr zostaną dołączone na końcu pliku .
  • < plik oznacza, że ​​standardowe wejście zostanie odczytane z pliku .
  • << string jest tutaj dokumentem . Stdin odczyta następujące wiersze aż do tego, który pasuje do string .

Samo przekierowanie stderr nie jest możliwe bez pomocy podpowłoki.

   mkfifo ~/filter  setenv  filter  "~/filter"  cat  $filter  &  (  (  ls /root/ ||  echo  Brak dostępu.  )  >  $filter  )  >& /dev/null 

Łączący

Polecenia można łączyć w tej samej linii.

  • ; oznacza uruchomienie pierwszego polecenia, a następnie następnego.
  • && oznacza uruchomienie pierwszego polecenia i, jeśli powiedzie się z kodem powrotu 0 , uruchomienie następnego.
  • || oznacza uruchomienie pierwszego polecenia, a jeśli zakończy się niepowodzeniem z niezerowym kodem powrotu, uruchom następne.

Rurociąg

Polecenia można łączyć za pomocą potoku, co powoduje, że wyjście jednego polecenia jest podawane na wejście następnego. Oba polecenia działają jednocześnie .

  • | oznacza połączenie stdout ze stdin następnego polecenia. Błędy nadal pojawiają się w oknie powłoki.
  • |& oznacza połączenie zarówno stdout, jak i stderr ze stdin następnego polecenia.

Bieganie współbieżne oznacza „równolegle”. W wielordzeniowym (wieloprocesorowym) polecenia przesyłane potokowo mogą być dosłownie wykonywane w tym samym czasie, w przeciwnym razie program planujący w systemie operacyjnym dokonuje odstępów czasowych między nimi.

Biorąc pod uwagę polecenie, np. „ a | b ”, powłoka tworzy potok , a następnie uruchamia zarówno a, jak i b ze stdio dla dwóch przekierowanych poleceń, tak że a zapisuje swoje stdout na wejściu potoku, podczas gdy b odczytuje stdin z wyjścia rury. Potoki są implementowane przez system operacyjny z pewną ilością buforowania, dzięki czemu a może pisać przez chwilę, zanim potok się zapełni, ale gdy potok się wypełni, każdy nowy zapis zostanie zablokowany w systemie operacyjnym, dopóki b nie odczyta wystarczającej ilości, aby odblokować nowe zapisy. Jeśli b spróbuje odczytać więcej danych niż jest dostępnych, będzie blokować, dopóki a nie zapisze więcej danych lub dopóki potok się nie zamknie, np. jeśli a zakończy działanie.

Podstawianie zmiennych

Jeśli słowo zawiera znak dolara „ $ ”, następujące znaki są traktowane jako nazwa zmiennej, a odwołanie jest zastępowane wartością tej zmiennej. Różne operatory edycyjne, wpisywane jako sufiksy do odniesienia, pozwalają na edycję nazwy ścieżki (np. " :e ", aby wyodrębnić tylko rozszerzenie) i inne operacje.

Cytowanie i ucieczka

Mechanizmy cytowania umożliwiają traktowanie znaków specjalnych, takich jak spacje, symbole wieloznaczne, nawiasy i znaki dolara, jako tekstu dosłownego .

  • \ oznacza przyjęcie następnego znaku jako zwykłego znaku dosłownego.
  • string to słaby cytat. Zamknięte spacje i symbole wieloznaczne są traktowane jako literały, ale nadal wykonywane są podstawienia zmiennych i poleceń.
  • string to mocny cytat. Cały załączony ciąg jest traktowany jako literał.

Podwójne cudzysłowy wewnątrz podwójnych cudzysłowów powinny być poprzedzone "\"" . To samo dotyczy symbolu dolara, aby zapobiec interpretacji zmiennej "\$" . W przypadku kresek wstecznych, aby zapobiec zagnieżdżaniu się poleceń, wymagane są pojedyncze cudzysłowy "'\`'" .

Zastąpienie polecenia

Podstawianie poleceń umożliwia użycie danych wyjściowych jednego polecenia jako argumentów dla innego.

  • ` polecenie ` oznacza pobranie danych wyjściowych polecenia , przetworzenie ich na słowa i wklejenie ich z powrotem do wiersza poleceń.

Poniżej znajduje się przykład zagnieżdżonych podstawień poleceń.

  echo  "`echo "  \"  '`echo "\"'  \'  '`echo "\"'  \'\\\'\'  '`echo "\"'  \'\\\'\\\\\\ \'\\\'\'  '`echo "\"'  \'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\\\ \\'\\\'\'  '`echo "\"'  \'\\\'\\\\\\\'\\\\\\\\\\\\\\\'\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\\'\\\\\\ \'\\\'\'  '`echo "\`"pwd"\`"`'  \'\\\'\\\\\\\'\\\\\\\\\\\\\\ \'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\\\\\\\\\\\\\\' \\\\\\\'\\\'\'  '\""`'  \'\\\'\\\\\\\'\\\\\\\\\\\\\\\' \\\\\\\'\\\'\'  '\""`'  \'\\\'\\\\\\\'\\\'\'  '\""`'  \'\\ \'\'  '\""`'  \'  '\""`'  \  " "`" 

Wykonanie w tle

Normalnie, gdy powłoka C uruchamia polecenie, czeka na zakończenie polecenia, zanim wyświetli użytkownikowi kolejną zachętę sygnalizującą, że można wpisać nowe polecenie.

  • polecenie & oznacza uruchomienie polecenia w tle i natychmiastowe zapytanie o nowe polecenie.

podpowłoki

Podpowłoka to oddzielna kopia podrzędna powłoki, która dziedziczy bieżący stan, ale może następnie wprowadzać zmiany, np. w bieżącym katalogu, bez wpływu na rodzica.

  • ( polecenia ) oznacza uruchamianie poleceń w podpowłoce.

Struktury kontrolne

Powłoka C zapewnia struktury kontrolne zarówno do testowania warunków, jak i iteracji . Struktury kontrolne do testowania warunków to instrukcje if i switch. Struktury kontroli iteracji to instrukcje while, foree i repeat.

Jeśli stwierdzenie

Istnieją dwie formy instrukcji if . Krótka forma jest wpisywana w jednym wierszu, ale może określać tylko jedno polecenie, jeśli wyrażenie jest prawdziwe.

  polecenie  if  (  wyrażenie  ). 

Długa forma wykorzystuje słowa kluczowe then, else i endif, aby umożliwić zagnieżdżanie bloków poleceń w warunku.

  
      
    
     if  (  wyrażenie1  )  to  komendy  else if  (  wyrażenie2  )  to  komendy ...  else  komendy  endif 

Jeśli słowa kluczowe else i if pojawiają się w tej samej linii, csh łączy je w łańcuchy, a nie zagnieżdża; blok jest zakończony pojedynczym endif.

instrukcja przełączania

Instrukcja switch porównuje ciąg z listą wzorców, które mogą zawierać symbole wieloznaczne. Jeśli nic nie pasuje, wykonywana jest akcja domyślna, jeśli taka istnieje.

 
    

 switch  (  string  )  przypadek  wzorzec1: komendy  przerwaw  przypadek  wzorzec2: komendy  przerwaw  ...  domyślnie  : komendy  przerwaw  koniecw 

podczas gdy oświadczenie

Instrukcja while ocenia wyrażenie. Jeśli to prawda, powłoka uruchamia zagnieżdżone polecenia, a następnie powtarza je tak długo, jak długo wyrażenie pozostaje prawdziwe.

  polecenia  while  (  wyrażenie  )  kończą się 

oświadczenie fore

Instrukcja foreach pobiera listę wartości, zwykle listę nazw plików utworzoną przez symbole wieloznaczne, a następnie dla każdej z nich ustawia zmienną pętli na tę wartość i uruchamia zagnieżdżone polecenia.

 komendy  foreach  dla zmiennych pętli  (  list-of-values  )  kończą się 

powtórz oświadczenie

Instrukcja repeat powtarza pojedyncze polecenie całkowitą liczbę razy.

 powtórz  polecenie całkowitoliczbowe 

Zmienne

Powłoka C implementuje zarówno zmienne powłoki, jak i zmienne środowiskowe . Zmienne środowiskowe utworzone za pomocą setenv są zawsze prostymi ciągami znaków przekazywanymi do procesów potomnych , które pobierają te zmienne za pomocą argumentu envp[] funkcji main() .

Zmienne powłoki, utworzone za pomocą instrukcji set lub @ , są wewnętrzne w powłoce C. Nie są one przekazywane do procesów potomnych. Zmienne powłoki mogą być prostymi łańcuchami lub tablicami ciągów. Niektóre zmienne powłoki są predefiniowane i używane do kontrolowania różnych wewnętrznych opcji powłoki C, np. co powinno się stać, jeśli symbol wieloznaczny nie pasuje do niczego.

W aktualnych wersjach csh łańcuchy znaków mogą mieć dowolną długość, sięgającą nawet milionów znaków.

Wyrażenia

Powłoka C implementuje 32-bitową gramatykę wyrażeń całkowitych z operatorami zapożyczonymi z C, ale z kilkoma dodatkowymi operatorami do porównywania łańcuchów i testów systemu plików, np. sprawdzania istnienia pliku. Operatory muszą być oddzielone białymi znakami od ich operandów. Zmienne są odwoływane jako $ nazwa .

Pierwszeństwo operatorów jest również zapożyczone z C, ale z innymi regułami asocjatywności operatorów , aby rozwiązać niejednoznaczność tego, co jest pierwsze w sekwencji operatorów o równym priorytecie. W C asocjatywność jest od lewej do prawej dla większości operatorów; w powłoce C jest od prawej do lewej. Na przykład,


       
    
      
    
      
     // grupy C od lewej  int  i  =  10  /  5  *  2  ;  printf  (  "%d  \n  "  ,  i  );  // drukuje 4  i  =  7  -  4  +  2  ;  printf  (  "%d  \n  "  ,  i  );  // drukuje 5  i  =  2  >>  1  <<  4  ;  printf  (  "%d  \n  "  ,  i  );  // drukuje 16 
        
   # Grupy powłok C od prawej  @  i  =  10 / 5 * 2  echo  $i  # wyświetla 1  @  i  =  7 - 4 + 2  echo  $i  # wyświetla 1  @  i  =  (  2 >> 1 << 4  )  echo  $i  # drukuje 0 

Nawiasy w przykładzie powłoki C mają na celu uniknięcie pomylenia operatorów przesuwających bity z operatorami przekierowania wejścia/wyjścia. W obu językach zawsze można użyć nawiasów, aby wyraźnie określić pożądaną kolejność oceny, nawet jeśli tylko dla jasności.

Przyjęcie

Chociaż sam Stephen Bourne przyznał, że csh jest lepszy od jego powłoki w interaktywnym użyciu, nigdy nie był tak popularny w pisaniu skryptów. Początkowo iw latach 80. nie można było zagwarantować, że csh będzie obecny we wszystkich systemach uniksowych, ale sh mógł, co czyniło go lepszym wyborem dla wszelkich skryptów, które mogą działać na innych komputerach. W połowie lat 90. csh był szeroko dostępny, ale użycie csh do pisania skryptów spotkało się z nową krytyką ze strony komitetu POSIX , który określił, że powinna istnieć tylko jedna preferowana powłoka, KornShell , zarówno do celów interaktywnych, jak i skryptowych. Powłoka C spotkała się również z krytyką ze strony innych osób za rzekome wady składni powłoki C, brakujące funkcje i słabą implementację.

  • Wady składniowe: były to na ogół proste, ale niepotrzebne niespójności w definicji języka. Na przykład set , setenv i alias robiły zasadniczo to samo, a mianowicie kojarzyły nazwę z łańcuchem lub zestawem słów. Ale wszyscy trzej mieli niewielkie, ale niepotrzebne różnice. Znak równości był wymagany dla zestawu , ale nie dla setenv lub alias ; nawiasy były wymagane wokół listy słów dla zestawu , ale nie dla setenv lub alias itp. Podobnie konstrukcje if , switch i looping używają niepotrzebnie różnych słów kluczowych ( endif , endsw i end ) do zakończenia zagnieżdżonych bloków.
  • Brakujące funkcje: najczęściej wymieniane są brak możliwości niezależnej manipulacji uchwytami plików stdio oraz obsługa funkcji. Chociaż brakuje obsługi funkcji, aliasy służą jako obejście. W przypadku wielu wierszy kodu aliasy muszą znajdować się w pojedynczych cudzysłowach, a każdy koniec wiersza musi poprzedzać ukośnik odwrotny (koniec ostatniego wiersza musi poprzedzać pojedynczy cudzysłów, aby rozgraniczyć koniec aliasu).
  • Implementacja, która wykorzystywała parser ad hoc , spotkała się z najpoważniejszą krytyką. We wczesnych latach siedemdziesiątych kompilatorów była na tyle dojrzała, że ​​większość nowych implementacji językowych korzystała z parsera typu top-down lub bottom-up, zdolnego do rozpoznawania w pełni rekurencyjnej gramatyki . Nie wiadomo, dlaczego zamiast tego wybrano projekt ad hoc dla powłoki C. Może być po prostu tak, jak Joy ujął to w wywiadzie w 2009 roku: „Kiedy zacząłem robić te rzeczy z Unixem, nie byłem zbyt dobrym programistą”. Projekt ad hoc oznaczał, że język powłoki C nie był w pełni rekurencyjny. Istniały ograniczenia co do tego, jak złożone polecenie mogło obsłużyć.

Działało to w przypadku większości interaktywnych poleceń, ale w przypadku bardziej złożonych poleceń, które użytkownik mógł napisać w skrypcie, mogło łatwo zawieść, generując tylko tajemniczy komunikat o błędzie lub niepożądany wynik. Na przykład powłoka C nie mogła obsługiwać orurowania między strukturami kontrolnymi. Próba przesłania danych wyjściowych polecenia foreach do grep po prostu nie zadziałała. (Obejście, które działa w przypadku wielu skarg związanych z analizatorem składni, polega na rozbiciu kodu na osobne skrypty. Jeśli foreach zostanie przeniesiony do osobnego skryptu, potokowanie działa, ponieważ skrypty są uruchamiane przez rozwidlenie nowej kopii csh, który dziedziczy poprawne uchwyty stdio).

Innym przykładem jest niepożądane zachowanie w poniższych fragmentach. Oba wydają się oznaczać: „Jeśli„ mój plik ”nie istnieje, utwórz go, wpisując w nim„ mój tekst ”. Ale wersja po prawej stronie zawsze tworzy pusty plik, ponieważ kolejność oceny powłoki C polega na wyszukiwaniu i ocenianiu operatorów przekierowania we/wy w każdym czytanym wierszu poleceń, przed sprawdzeniem reszty wiersza, aby zobaczyć, czy zawiera strukturę kontrolną.


  
    # Działa zgodnie z oczekiwaniami  if  (  ! -e myfile  )  then  echo  mytext > myfile endif 

   # Zawsze tworzy pusty plik,  jeśli  (  ! -e mój plik  )  echo  mój tekst > mój plik 

    # Obejście (tylko dla tcsh)  if  (  ! -e myfile  )  eval  "echo mytext > myfile" 

Implementacja jest również krytykowana za notorycznie słabe komunikaty o błędach, np. „0: Nie znaleziono zdarzenia.”, które nie dostarczają żadnych użytecznych informacji o problemie.

Jednak poprzez praktykę możliwe jest przezwyciężenie tych niedociągnięć (w ten sposób instruując programistę, aby przyjął lepsze i bezpieczniejsze podejście do implementacji skryptu).


     # Drugie obejście (dla csh i tcsh)  (  (  : < myfile  )  >& /dev/null &&  echo  Plik istnieje.  )  ||  (  (  echo  mój tekst > mój plik  )  >& /dev/null &&  echo  Utworzono plik.  )  ||  (  echo  Nie można utworzyć pliku.  ) 

„0: nie znaleziono zdarzenia”. błąd oznacza, że ​​w historii nie ma zapisanych poleceń. Historia może nie działać poprawnie w skryptach, ale posiadanie wstępnie ustawionego zestawu poleceń w zmiennej służy jako obejście problemu.


  

  
  
    #!/bin/csh -f  set  cmdlist  =  "`cat .cmdlist`"  echo  -n  'Wprowadź liczbę, aby wykonać polecenie z historii: '  set  cmdexec  =  "$<"  (  echo  $cmdexec  | grep -qa  ' [^0-9]'  &&  \  echo  'Musi to być liczba.'  )  &&  exit  1  `  echo  $cmdlist  [  $cmdexec  ]  `  ||  \  cat -n .cmdlist 

Wpływ

64-bitowa powłoka Hamilton C na komputerze z systemem Windows 7 .

Powłoka C odniosła ogromny sukces, wprowadzając wiele innowacji, w tym mechanizm historii , aliasy , notację tyldy , interaktywne uzupełnianie nazw plików, gramatykę wyrażeń wbudowaną w powłokę i wiele innych, które od tego czasu zostały skopiowane przez inne powłoki systemu Unix. Ale w przeciwieństwie do sh , który dał początek dużej liczbie niezależnie opracowanych klonów, w tym ksh i bash , znane są tylko dwa klony csh . (Ponieważ tcsh był oparty na kodzie csh pierwotnie napisanym przez Billa Joya, nie jest uważany za klon).

W 1986 roku Allen Holub napisał On Command: Writing a Unix-Like Shell for MS-DOS , książkę opisującą napisany przez niego program o nazwie „SH”, który w rzeczywistości skopiował projekt języka i funkcje csh, a nie sh. Dyskietki towarzyszące zawierające pełne źródła SH i podstawowy zestaw narzędzi uniksopodobnych (cat, cp, grep itp.) Były dostępne u wydawcy za odpowiednio 25 i 30 dolarów. Struktury kontrolne, gramatyka wyrażeń, mechanizm historii i inne cechy w SH Holuba były identyczne jak w powłoce C.

W 1988 roku Hamilton Laboratories rozpoczęło wysyłkę powłoki Hamilton C dla systemu OS/2 . Zawierał zarówno klon csh, jak i zestaw narzędzi typu Unix. W 1992 roku została wydana powłoka Hamilton C dla systemu Windows NT . Wersja systemu Windows jest nadal aktywnie obsługiwana, ale wersja OS / 2 została wycofana w 2003 r. Krótkie odniesienie z początku 1990 r. Opisywało zamiar jako „pełną zgodność z całym językiem powłoki C (z wyjątkiem kontroli zadań)”, ale z ulepszeniami projektu języka i dostosowanie do różnic między Unixem a PC. Najważniejszym ulepszeniem był parser typu top-down , który pozwalał na zagnieżdżanie lub potokowanie struktur kontrolnych , czego oryginalna powłoka C nie mogła obsługiwać, biorąc pod uwagę jej parser ad hoc. Hamilton dodał również nowe funkcje językowe, w tym wbudowane i zdefiniowane przez użytkownika procedury, zmienne lokalne o strukturze blokowej i arytmetykę zmiennoprzecinkową. Dostosowanie do komputera PC obejmowało obsługę nazw plików i innych konwencji na komputerze PC oraz użycie wątków zamiast rozwidleń (które nie były dostępne ani w systemie OS / 2, ani w systemie Windows) w celu osiągnięcia równoległości , np. podczas konfigurowania potoku.

Zobacz też

Dalsza lektura

Linki zewnętrzne