Neden kabuk yerleşiklerin uygun erkek sayfaları yok?


32

Tüm kabuk yerleşikleri aynı manuel sayfayı paylaşır:

BUILTIN(1)                BSD General Commands Manual               BUILTIN(1)

NAME
     builtin, !

vb.

Sonra kabuk yapılarının ne olduğunu açıklayan küçük bir metin var ve sonra şunun gibi görünen bir liste var:

  Command       External    csh(1)    sh(1)
       !             No          No        Yes
       %             No          Yes       No

Ama eğer yaparsak, man grepgibi bölümleri alıyoruz

  • Hatalar
  • Tarihçe
  • Ayrıca bakınız
  • Standartlar
  • Açıklama

vb.

Builtins gibi kendi tarih, açıklama ve argümanları var kabuk etmeyin -Aya -r? Bu neden kılavuz sayfalarında verilmemiştir ve bunları doğru ve verimli kullanmayı nasıl öğrenebilirim?


Yanıtlar:


25

Çünkü yerleşikler kabuğun bir parçasıdır. Sahip oldukları herhangi bir hata veya tarih, kabuğun kendisinin hataları ve tarihidir. Bağımsız komutlar değillerdir ve içinde bulundukları kabuğun dışında varolmazlar.

En bashazından eşdeğeri helpkomuttur. Örneğin:

$ help while
while: while COMMANDS; do COMMANDS; done
    Execute commands as long as a test succeeds.

    Expand and execute COMMANDS as long as the final command in the
    `while' COMMANDS has an exit status of zero.

    Exit Status:
    Returns the status of the last command executed.

Bütün bash yerleşimlerinin helpsayfaları vardır. helpKendisi bile :

$ help help
help: help [-dms] [pattern ...]
    Display information about builtin commands.

    Displays brief summaries of builtin commands.  If PATTERN is
    specified, gives detailed help on all commands matching PATTERN,
    otherwise the list of help topics is printed.

    Options:
      -d    output short description for each topic
      -m    display usage in pseudo-manpage format
      -s    output only a short usage synopsis for each topic matching
        PATTERN

    Arguments:
      PATTERN   Pattern specifiying a help topic

    Exit Status:
    Returns success unless PATTERN is not found or an invalid option is given.

@ Mikeserv'in sedsenaryosundan ilham alan , işte Perl'i kullanarak bir man sayfasının ilgili bölümünü basacak küçük bir fonksiyon. Bu satırı kabuğunuzun başlatma dosyasına ekleyin ( ~/.bashrcbash için):

manperl(){ man "$1" | perl -00ne "print if /^\s*$2\b/"; }

Ardından, bir man sayfası ve bir bölümün adını vererek çalıştırın:

$ manperl bash while
       while list-1; do list-2; done
       until list-1; do list-2; done
              The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit
              status of zero.  The until command is identical to the while command, except that the test is negated; list-2 is  exe‐
              cuted  as  long  as the last command in list-1 returns a non-zero exit status.  The exit status of the while and until
              commands is the exit status of the last command executed in list-2, or zero if none was executed.

$ manperl grep SYNOPSIS
SYNOPSIS
       grep [OPTIONS] PATTERN [FILE...]
       grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

$ manperl rsync "-r"
       -r, --recursive
              This tells rsync to copy directories recursively.  See also --dirs (-d).

2
Onlar @DisplayName olan bash. Onlar bunun bir parçasıdır ve evet, man sayfasının SHELL BUILTIN COMMANDSbölümünde açıklanmıştır bash. Onların "man sayfaları" dır help builtin_name.
terdon

3
Açık olmayan, neden onlara adam sayfaları verilmediğidir. Man sayfaları sadece MANPATH'teki dosyalardır. Ayrı ikili dosyalara karşılık gelmek zorunda değiller. Prensetin, dahili yardım sistemine sahip olmaktansa, bash’ın yerleşimleri için kılavuz sayfaları ile gönderilememesi için hiçbir neden yoktur.
Francis Davey

4
@FrancisDavey: Ancak çoğu yerleşik, çeşitli kabuklarda (farklı uzantılara sahip) var. Man sayfaları kabuğa özgü değildir; sistem çapındadırlar.
rici,

2
@ FrancisDavey rici'nin dediği gibi, komutlar sistem çapında değildir. Bu biraz her kabuk mevcut değil, ama daha da kötüsü, çok bir komut için bir adam sayfası sahibi olmak kafa karıştırıcı olacak bir komut için bir manpage olması yanıltıcı olacağını ise birden kabukları bulunan, ancak hangi davranışı farklı (örneğin , farklı argümanları kabul eder, farklı sözdizimlerine sahiptir, vb.).
Joshua Taylor

1
@mikeserv Ancak, ben ederim nerede, ne örn git teklifler, çizgisinde kabuk yerleşikleri için man sayfalarına hoş geldiniz man git commitiçin adam sayfası açılıyor git-commit. Gibi bir şey harikaman bash if olurdu .
Joshua Taylor

5

Bazı kabuk builtins bir kıt tam manuel gösterilmesini olabileceğini bunun doğru olsa - özellikle olanlar için bashbir GNU sisteminde kullanılmak üzere sadece olasılığınız olduğunu 'e özgü yerleşikleri inanmıyorum, kural olarak (GNU millet, manve kendi infosayfalarını tercih et )) - POSIX araçlarının büyük çoğunluğu - kabuk yapı taşları veya başka türlü - POSIX Programcı El Kitabı'nda çok iyi bir şekilde temsil edilmektedir.

İşte benim altından bir alıntı man sh (muhtemelen 20 sayfa ya da öylesine ...)

görüntü tanımını buraya girin

Bunların tamamı vardır ve diğerleri böyle belirtilmeyen set, read, break... şey, ben hepsini isim gerekmez. Ancak (1P)sağ alt köşede - POSIX kategori 1 manuel serisinin - bunlar manhakkında konuştuğum sayfalar olduğunu gösterir.

Sadece bir paket yüklemeniz gerekebilir mi? Bu bir Debian sistemi için umut verici görünüyor. helpYararlı olsa da, bulabilirseniz kesinlikle bu POSIX Programmer's Guidediziyi almalısınız . Son derece yardımcı olabilir. Ve kurucu sayfaları çok ayrıntılı.

Bu bir yana, kabuk yerleşikleri neredeyse her zaman belirli kabuğun kullanım kılavuzunun belirli bir bölümünde listelenir. zsh, örneğin, bunun için ayrı bir mansayfa var - (8 ya da 9 ya da öylesine ayrı zshsayfalarda toplandığını düşünüyorum zshall.

grep manTabii ki sadece :

man bash 2>/dev/null | 
grep '^[[:blank:]]*read [^`]*[-[]' -A14

   read [-ers] [-a aname] [-d  delim]  [-i  text]  [-n
   nchars]  [-N  nchars]  [-p prompt] [-t timeout] [-u
   fd] [name ...]
          One line is read from the standard input, or
          from  the  file descriptor fd supplied as an
          argument to the -u  option,  and  the  first
          word is assigned to the first name, the sec‐
          ond word to the second name, and so on, with
          leftover words and their intervening separa‐
          tors assigned to the last  name.   If  there
          are  fewer  words read from the input stream
          than names, the remaining names are assigned
          empty  values.   The  characters  in IFS are
          used to split the line into words using  the
          same  rules  the  shell  uses  for expansion

... bir kabuk mansayfasını ararken yaptığım işe oldukça yakın . Ancak çoğu durumda helpoldukça iyidir bash.

sedSon zamanlarda bu tür şeyleri halletmek için bir senaryo üzerinde çalışıyorum . Resimdeki bölümü bu şekilde yakaladım. Hala sevdiğimden daha uzun, ama gelişiyor - ve oldukça kullanışlı olabilir. Mevcut yinelemesinde, komut satırında verilen [a] desenine [s] dayanarak bir bölüme veya alt bölüm başlığına eşleştirildiği gibi içeriğe duyarlı bir metin bölümünü oldukça güvenilir bir şekilde çıkaracaktır. Çıktısını renklendirir ve stdout'a yazdırır.

Girinti düzeylerini değerlendirerek çalışır. Boş olmayan giriş satırları genellikle göz ardı edilir, ancak boş bir satırla karşılaştığında dikkat etmeye başlar. Geçerli dizinin kesinlikle başka bir boş satır oluşmadan önce ilk satırından daha fazla girintili olduğunu doğrulayana kadar çizgileri oradan toplar veya ipliği düşürür ve bir sonraki boşluğu bekler. Sınama başarılı olursa, kılavuz çizgisini komut satırı argümanlarıyla eşleştirmeye çalışır.

Bu, bir eşleşme deseninin eşleşeceği anlamına gelir :

heading
    match ...
    ...
    ...
        text...

..ve..

match
   text

..Ama değil..

heading
    match
    match

    notmatch

..veya..

         text

         match
         match
         text

         more text

Bir eşleşme elde edilebilirse, yazdırmaya başlar. Eşleştirilen çizginin önde gelen boşluklarını yazdırdığı tüm satırlardan sıyırır - bu nedenle girinti düzeyi üzerinde olursa olsun, üzerinde bulunan çizgiyi en tepedeymiş gibi yazdırır. Eşleştirilen çizgiden eşit veya daha az girintili bir çizgide başka bir çizgiyle karşılaşıncaya kadar yazdırmaya devam eder - bu nedenle tüm bölümler içerebilecek tüm alt bölümleri, paragrafları da içeren yalnızca bir başlık eşleştirmesiyle yakalanır.

Temel olarak, bir desenle eşleşmesini isterseniz, bunu sadece bir tür konu başlığına karşı yapar ve eşleşmesinin başlığında bulunan bölümde bulunan tüm metni renklendirir ve yazdırır. İlk satırınızın girintisi dışında hiçbir şey kaydedilmez - ve çok hızlı olabilir ve \newline ayrılmış herhangi bir büyüklükteki girişi ele alabilir.

Aşağıdakiler gibi alt pozisyonlara nasıl tekrar gireceğimi bulmam biraz zaman aldı:

Section Heading
    Subsection Heading

Ama sonunda hallettim.

Yine de sadelik uğruna her şeyi elden geçirmek zorunda kaldım. Daha önce aynı şeyleri kendi bağlamlarına uyacak şekilde biraz farklı şekillerde yapan birkaç küçük döngüye girmeden önce, özyineleme yöntemlerini değiştirerek kodun çoğunluğunu kopyalamayı başardım. Şimdi iki döngü var - biri yazdırıyor, diğeri kontrol girinti. Her ikisi de aynı teste bağlıdır - test döngüsü geçtiğinde yazdırma döngüsü başlar ve başarısız olduğunda veya boş bir satırda başladığında girinti döngüsü devreye girer.

Tüm süreç çok hızlı çünkü çoğu zaman /./dboş olmayan herhangi bir çizgiyi siliyor ve bir sonrakine geçiyor - hatta zshallekranın anında doldurulmasından bile kaynaklanıyor . Bu değişmedi.

Neyse, şu ana kadar çok faydalı. Örneğin, readyukarıdaki şey şöyle yapılabilir:

mansed bash read

... ve tüm bloğu alır. Birincisi her zaman manarama yapması gereken sayfa olmasına rağmen, herhangi bir desen veya her hangi bir şekilde veya birden fazla argüman alabilir . İşte yaptıktan sonra çıktısının bir kısmı :

mansed bash read printf

görüntü tanımını buraya girin

... her iki blok da bir bütün olarak geri döndü. Sık sık şöyle kullanırım:

mansed ksh '[Cc]ommand.*'

... oldukça yararlı olduğu için. Ayrıca, almak SYNOPS[ES]gerçekten çok kullanışlı:

görüntü tanımını buraya girin

İşte bir koşuşturma vermek istersen - Söylemezsen seni suçlamayacağım.

mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
    /\n/!{  /./{    \$p;d
        };x;    /.*\n/!g;s///;x
    :indent
        /.*\n\n/{s///;x
        };n;\$p;
        /^\([^${s}].*\)*$/{s/./ &/;h;   b indent
        };x;    s/.*\n[^-[]*\n.*//; /./!x;t
        s/[${s}]*$//;   s/\n[${b}]\{2,\}/${n} /;G;h
    };
    #test
    /^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
        s//\1\2.\3/
    :print
    /^[${s}]*\n\./{ s///;s/\n\./${n}/
        /${bs}/{s/\n/ & /g;
            s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
            s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
            s/.${bs}//g;s/ \n /${n}/g
            s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
        };p;g;N;/\n$/!D
        s//./;  t print
    };
    #match
        s/\n.*/ /;  s/.${bs}//g
        s/^\(${match}\).*/${n}\1/
        /../{   s/^\([${s}]*\)\(.*\)/\1${n}/
        x;  s//${n}\1${n}. \2/; P
    };D
");}

Kısaca, iş akışı:

  • boş olmayan ve \newline karakter içermeyen herhangi bir satır çıktıdan silinir.
    • \newline karakterleri hiçbir zaman giriş deseni alanında gerçekleşmez. Yalnızca bir düzenlemenin sonucu olabilirler.
  • :printve :indenther ikisi de karşılıklı olarak bağımlı olan kapalı halkalardır ve \newline elde etmenin tek yoludur .
    • :printBir satırdaki \nbaş karakterlerin ewline karakteriyle başlayan bir dizi boşluk olması durumunda döngü döngüsü başlar .
    • :indentdöngüsü boş satırlarda - veya :printbaşarısız olan döngü satırlarında #test- ancak :indenttüm boş + \newline dizilerini çıkışından kaldırır .
    • Bir kez :printbaşladıktan sonra, giriş hatlarını çekmeye devam edecek, öncü boşluk alanını çevrimindeki ilk satırda bulunan miktara kadar soyun, aşırı gerilmeyi çevirip geri tepme kaçışlarını renkli terminal kaçışlarına çevirip #testbaşarısız olana kadar yazdırın .
    • önce :indentbaşlamadan önce hherhangi bir olası girinti devamı (Altbölüm gibi) için eski alanı kontrol eder ve sonra #testbaşarısız olduğu sürece girdi çekmeye devam eder ve ilkini izleyen herhangi bir satır eşleşmeye devam eder [-. İlk satırdan sonraki bir satır bu modelle eşleşmediğinde silinir - ve ardından bir sonraki boş satıra kadar olan tüm satırlar takip eder.
  • #matchve #testiki kapalı döngüyü köprüleyin.
    • #test\nÖndeki boşluk serileri, satır dizisindeki son satırın arkasındaki diziden daha kısa olduğunda geçer .
    • #matchherhangi bir komut satırı \nargümanı ile eşleşmeye yol açan herhangi bir çıkış dizisine bir :printdöngüye başlamak için gerekli olan öncü hatları hazırlar :indent. Boş bırakılmayan diziler - ve sonuçta ortaya çıkan boş satır geri döndürülür :indent.

2
Sed-fu'nuz güçlü. Elbette, aynı şeyi manperl(){ man $1 | perl -00ne "print if /^\s*$2\b/"; }ve sonra manperl sh SYNOPSISda yapabilirsiniz: manperl sh read:)
terdon

@ terdon - hayır, yapamazsınız. Bu girdi yemiyor. Ben de aynı şeyi yapabilirim sed 'H;$!d;g;s/\(\(\n *\)match\([^\n]*\)\2 \)\{1,\}\)*.\{,1\}/\1/g'... muhtemelen işe yarar ... ama bu dosyayı yutmayı ve hepsini bir kerede ayrıştırmayı gerektirir. Bu bir akışta çalışır - çizgilerin astronomik olarak uzun olmaması şartıyla her boyuttaki girişi kaldırabilir. Çalışır gibi basar - ve tüm ayrıştırır man'ın \backslash kaçar için önyükleme. Ama manbunun için sadece tek bir uygulama - Ben de diğer sorunlara da
uyguladım

1
Sadece zincirinizi sallıyorum, çünkü ne anlattığınızı küçük bir astarla yapabiliyorum. Ancak, dosyayı bütün olarak yutmadığını, bir akışta çalıştığını unutmayın. Sadece \n\nbunun yerine "satırları" tanımlar , \nancak yine de herhangi bir boyuttaki girişi kaldırabilir ve çalışır şekilde yazdırır. Burada "paragraf modu" bölümüne bakınız: perldoc.perl.org/perlrun.html
terdon

@ terdon Belki bu, buraya gitmek için daha iyi bir yol olurdu. In sedböyle yapılabilir: '/./{H;$!d' -e '};x;now work the paragraph...'. Bunu da sıklıkla yaparım. Ama başlangıçta bir kütüğü sınırsız süre boyunca canlı izlemeye başlamanın ilk bölümünü yazdım ve bu davranış bile başarısız oldu - arabellek belirli koşullar altında patlayabilir. Bu boyutun sadece yarısı kadardı - manzorlaştırdı. Yukarıdaki synop'u man -Haldıktan sonra baktım ve mangroff'un GNU sistemlerinde yazdırabileceği makine-HTML ile çalışmanın daha kolay olabileceğini düşünüyorum. Ben zaten dirsek-derin zaten
thoug

@terdon - Kendimi ikinci kez tahmin ettim ve paragraf merkezli bir yaklaşım denedim, ancak olduğu gibi daha kolay. Bu bölümleri alır. Gibi mansed cmd DESCRIPTIONAÇIKLAMA bölüm alır - ve hepsi dahil olanlar. Eşleşen bir arama bütün olarak basılır ve sanki girinti seviyesi en üst düzeydeydi. Hatta eşleşen ama o zaman daha fazla girintisi olmayan paragrafları göz ardı ederek yanlış pozitifleri atlar. Artan renk geri kaçakları arasından çıkan kenarlarıyla eşleşir ve kesinlikle bir çizgi yazdırmaya hazır olana kadar bunları kullanmaz. Bunların hepsi bir seferde tek bir satırdan çok daha fazla veriyle yapmak için çok zor.
mikeserv

1

Her kabuğun kendine ait yerleşik kümesi vardır. Ortaklıklar varken, her birinin belgelenmesi gereken kendi özellikleri vardır.

Her kabuğun ayrı bir paket olarak sağlandığı Linux ve FreeBSD (ve FreeBSD'den miras kalan OSX) gibi sistemlerde, yerleşikler için bir kılavuz sayfası yoktur; bunun yerine, her bir yerleşim yeri kabuğun man sayfasında belgelenmiştir. Yani Bash'in belgelenmesi için bash man sayfasına killyerleşiğini, tire en belgelenmesi için çizgi man sayfasına killbir adam sayfası da var vs. yerleşiğini, killbağımsız bir yardımcı.

Bkz Can I komutları yerleşik partisi yüzünden bireysel man sayfalarına olsun? manargümanın bir yerleşimin adı olması halinde bash'ın man sayfası yerine iç belgelerini gösteren bir işlev için .

Kabuk yapıları için insan sayfaları sağlayan unix varyantları var - aslında çoğu ticari varyantlar. Bu uygulanabilir, çünkü sistem tek bir kabuk veya bilinen bir dizi kabukla birlikte gelir. Man sayfa kabukları arasındaki farkları tartışıyor. Örneğin, fg(1)Solaris 10'daki man sayfasınınsh , kshve için bölümleri vardır csh. fg(1)AIX 7.1 adam sayfası birlikte referanslar “Korn kabuk” ve “POSIX kabuk” ama tartışıyor onları (onlar için tam olarak aynı özellikleri desteklemek için ne fg). fg(1)Tru64 5.0 adam sayfası tartışıyor Ksh yerleşik ve csh kullanıcıları atıfta csh(1)adam sayfası. SCOgörünüşe göre tek bir kabuk ile birlikte geliyor. Diğer işletim sistemlerini bu işletim sistemlerine eklenti paketleri olarak yükleyebilirsiniz; Özel bir kabuk kullanıyorsanız, yerleşik olmayan bir kabuk kullanırken manşetlerin man sayfalarının alakalı olmayacağını unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.