Printf-kommandot Stranger, det här är ett mycket stort ämne som behöver erfarenhet - fyll i information som saknas, förläng beskrivningarna och korrigera detaljerna om du kan Attention: Det handlar om Bash-builtin-kommandofönstret - men beskrivningen ska vara nästan identisk för ett externt kommando som följer POSIX. GNU Awk förväntar sig ett kommatecken efter formatsträngen och mellan varje av argumenten för ett printf-kommando. För exempel, se: kodbit. Till skillnad från andra dokumentationer vill jag inte omdirigera dig till den manuella sidan för funktionen printf () C. Men om du är mer erfaren, bör det vara den mest detaljerade beskrivningen av formatsträngarna och modifierarna. På grund av motstridiga historiska implementeringar av ekokommandot rekommenderar POSIX att printf föredras framför eko. Printf-kommandot ger en metod för att skriva ut förformaterad text som liknar printf () systemgränssnittet (C-funktionen). It039s betydde som efterträdare för eko och har många fler funktioner och möjligheter. Förutom andra orsaker har POSIX ett mycket bra argument för att rekommendera det: Båda historiska huvudvarianterna av echo-kommandot är ömsesidiga exklusiva, de kolliderar. Ett quotnewquot-kommando måste uppfinnas för att lösa problemet. Textformatet ges i ltFORMATgt. medan alla argument som formatsträngen kan peka på ges efter det här, indikerat av ltARGUMENTSgt. Således ser en typisk printf-call ut: där quotSurname: snName: snquot är formatspecifikationen, och de två variablerna överförs som argument, s i formatstring pekar på (för varje format specifierare du ger, printf väntar på ett argument) . Om den ges, tilldelas utgången till variabel VAR i stället för tryckt till stdout (jämförbar med sprintf () på något sätt) - v Alternativ can039t tilldela direkt array-index i Bash-versioner som är äldre än Bash 4.1. I versioner som är nyare än 4.1 måste man vara försiktig när man utför expansioner i det första non-option-argumentet för printf, eftersom detta öppnar möjligheten för en enkel kodinsprutningssårbarhet. där ekot kan naturligtvis ersättas med alla godtyckliga kommandon. Om du måste, ange antingen en hårdkodad formatsträng eller använd - för att signalera slutet på alternativen. Exakt samma fråga gäller också för läsning. och en liknande till kartfilen. även om de utför utvidgningar i sina argument är mindre vanliga. Självklart är det i shell-mening att argumenten bara är strängar, men de gemensamma C-notationerna plus några tillägg för talkonstanterna är igenkända för att ge ett antal argument att skriva ut. Basalt är det en fråga om bärbarhet (och tillförlitlighet). I början accepterade echo inte något alternativ och utvidgade inte något. Allt det var att göra var att lägga ut sina argument åtskilda av ett mellanslag och avslutas av en newline-karaktär. Nu trodde någon att det skulle vara trevligt om vi kunde göra saker som echo nt för att mata ut newline eller fliktecken, eller ha ett alternativ att inte mata ut den efterföljande newline-karaktären. De tänkte då hårdare men istället för att lägga till den funktionen till skalet (som perl där inne dubbla citat, t betyder faktiskt en flik karaktär), de lagt till det för eko. David Korn insåg misstaget och introducerade en ny form av skalcitat:. som senare kopierades av bash och zsh men det var alldeles för sent vid den tiden. Nu när ett standard Unix-echo får ett argument som innehåller de två tecknen och t. istället för att mata ut dem, utmatas en fliktecken. Och så snart det ser c i ett argument, slutar det att mata ut (så den efterföljande newlineen matas inte heller ut). Andra shellsUnix leverantörerversioner valde att göra det annorlunda: de lade till ett - e alternativ för att expandera escape-sekvenser och ett - n alternativ att inte mata ut den efterföljande newlineen. Vissa har en - E för att inaktivera escape-sekvenser, vissa har - n men inte - e. listan över flyktsekvenser som stöds av en ekkoimplementering är inte nödvändigtvis densamma som stöds av en annan. På de eko-implementeringar som stöder alternativ, finns det i allmänhet inget stöd av a - för att markera slutet på alternativen (zsh och eventuellt andra stödjer - för det dock), så till exempel, det är svårt att utföra - n med eko i många skal. På vissa skalar som bash 1 eller ksh93 2 eller yash (ECHOSTYLE-variabel) beror uppförandet av hur skalet sammanställdes eller miljön (GNU-ekos beteende kommer också att förändras om POSIXLYCORRECT finns i miljön). Så två bash echo s, inte ens från samma version av bash garanteras inte att uppträda densamma. POSIX säger: om det första argumentet är - n eller något argument innehåller backslashes, är beteendet ospecificerat. bash echo i det avseendet är inte POSIX i att till exempel eko - e inte utmatas - tvätt som POSIX kräver. Unix-specifikationen är strängare, den förbjuder - n och kräver utvidgning av några flyktsekvenser inklusive den en som slutar utmatas. Dessa specifikationer kommer verkligen inte till räddning här med tanke på att många implementeringar inte överensstämmer. Sammantaget vet du inte vad echo var kommer att producera om du inte kan se till att var innehåller inte backslash tecken och börjar inte med -. POSIX-specifikationen säger faktiskt att vi ska använda printf istället i det fallet. Så vad det betyder är att du inte kan använda echo för att visa okontrollerad data. Med andra ord, om du skriver ett skript och det tar extern inmatning (från användaren som argument eller filnamn från filsystemet.), Kan du inte använda echo för att visa det. (Även om det kommer att fungera OK med vissa (icke-Unix) ekoimplementeringar som bash s när xpgecho-alternativet inte har aktiverats på ett eller annat sätt, som vid sammanställningstid eller via miljön). printf. å andra sidan är mer tillförlitlig, åtminstone när det är begränsat till den grundläggande användningen av eko. Kommer att skriva ut innehållet i var följt av en nylinje, oberoende av vilken karaktär den kan innehålla. Kommer att mata ut det utan den efterföljande newline-karaktären. Nu finns det också skillnader mellan printf-implementeringar. Det finns en kärna av funktioner som specificeras av POSIX, men då finns det många tillägg. Till exempel, vissa stödjer en q för att citera argumenten, men hur det görs varierar från skal till skal, vissa stödjer uxxxx för unicode-tecken. Uppförandet varierar för printf 10sn var i multi-byte-platser, det finns minst tre olika resultat för printf b 123 Men i slutändan, om du håller fast vid POSIX-funktionen set printf och försöker inte göra någonting för att ha det med dig, youre ur trubbel. Men kom ihåg att det första argumentet är formatet, så det borde inte innehålla variabelkontrollerade data. Ett mer pålitligt eko kan implementeras med printf. som: Underhöljet (vilket innebär att man spionerar en extra process i de flesta skal implementeringar) kan undvikas med hjälp av lokala IFS med många skal eller genom att skriva det som: 1. hur bash s echo behavior kan ändras. Med bash. vid körtiden finns det två saker som styr uppförandet eller ekot (vid sidan av aktivera - ett eko eller omdefiniera eko som en funktion eller ett alias): alternativet xpgecho bash och om bash är i posix-läge. posix-läge kan aktiveras om bash kallas sh eller om POSIXLYCORRECT finns i miljön eller med posix-alternativet: Standardbeteende på de flesta system: xpgecho expanderar sekvenser som Unix kräver: Det hedrar fortfarande - n och - e (och - E ): Med xpgecho och POSIX-läge: Denna gång är bash både POSIX och Unix conformant. Observera att i POSIX-läge är bash fortfarande inte POSIX-konformat eftersom det inte matar ut - e i: Standardvärdena för xpgecho och posix kan definieras vid sammanställningstiden med - enable-xpg-echo-default och - enable-strict - posix-standardalternativ till konfigurationsskriptet. Det är typiskt vad senaste versioner av OSX gör för att bygga sina binsh. Ingen UnixLinux implementationdistribution i sitt rätt sinne skulle normalt göra det för binbash men. 2. Hur ksh93 s eko beteende kan ändras. I ksh93. huruvida echo expanderar flyktsekvenser eller inte och känner igen alternativ beror på innehållet i PATH. Om PATH innehåller en komponent som innehåller 5bin eller xpg före bin eller usrbin-komponenten, uppför den sedan SysVUnix-sättet (expanderar sekvenser, accepterar inte alternativ). Om den finner ucb eller bsd först, uppträder den BSD 3-vägs (-e för att möjliggöra expansion, känner igen - n). Standard är systemberoende, BSD på Debian: 3. BSD för eko - e Referensen till BSD för hanteringen av - e-alternativet är vilseledande här. Alla dessa olika och oförenliga ekobeteenden introducerades alla i Bell Labs: n. 0ooo i Programmerare Arbetsbenk UNIX (baserat på Unix V6) och resten (b. C.) I Unix System III Ref. - n i Unix V7 (av Denis Ritchie Ref) - e i Unix V8 (av Denis Ritchie Ref) BSDs just descended från Unix V7. FreeBSD echo stödjer fortfarande inte - e. även om det stödjer - som Unix V7 gjorde. En fördel, om du vill kalla det så, skulle vara att du inte behöver säga det som eko för att tolka vissa flyktsekvenser som n. Det vet att tolka dem och behöver inte en-att göra det. (Obs: den sista n är nödvändig, eko innebär det, om du inte ger - n-alternativet) Notera den sista n i printf. I slutet av dagen är det en fråga om smak och krav vad du använder: echo eller printf. En nackdel med printf är prestanda eftersom det inbyggda skalets eko är mycket snabbare. Detta kommer in i spel speciellt i Cygwin där varje instans av ett nytt kommando orsakar tunga Windows-överhead. När jag ändrade mitt eko-tunga program från att använda binecho till skalen eko fördubblades prestationen nästan. Det är en avvägning mellan bärbarhet och prestanda. Det är inte en slam dunk att alltid använda printf. svarat 3 okt 14 kl 17.00 Kommandot Linux och Unix printf FORMAT-strängen innehåller tre typer av objekt: vanliga tecken. som kopieras ordentligt till utgången. tolkade teckensekvenser, som släpps med en backslash (). konvertering specifikationer, som definierar hur ARGUMENT s kommer att uttryckas som en del av produktionen. Här är ett snabbt exempel som använder dessa tre typer av objekt: Detta kommando ger output: Här är FORMAT bifogad i dubbla citat (). Det finns en omvandlingsspecifikation: s. vilken tolkar argumentet John som en sträng och sätter in det i utmatningen. Det finns tre flyktiga karaktärsekvenser: två förekomster av och en förekomst av n. Sekvensen översätts som ett bokstavligt dubbelkvot det släpps med en backslash så att printf kan behandla det som en bokstavlig karaktär, och inte som slutet av FORMAT-strängen. n är sekvensen för en ny linje, och berättar printf att starta en ny linje och fortsätta utmatningen därifrån. Effekten av printf ligger i att för en given FORMAT-sträng kan ARGUMENT s ändras för att påverka utmatningen. Till exempel kan utmatningen av kommandot i ovanstående exempel ändras bara genom att ändra argumentet, John. Om det används i ett skript. Detta argument kan ställas in på en variabel. Kommandot kommer till exempel att infoga värdet för miljövariabeln LOGNAME. vilket är användarnamnet för den som körde kommandot. Konverteringsspecifikationer Varje omvandlingsspecifikation börjar med a och slutar med ett konverteringstecken. Mellan och omvandlingspersonen kan det vara, i ordning: Ett minustecken. Detta berättar printf till vänster - justera omvandlingen av argumentet. Ett heltal som anger fältbreddsutskrift kommer att skriva ut en konvertering av ARGUMENT i ett fält minst antal tecken breda. Om det behövs kommer det att polstras till vänster (eller höger, om vänsterjustering krävs) för att fylla på fältbredden. En period som skiljer fältets bredd från precisionen. Ett heltal, precisionen, som anger det maximala antalet tecken som ska skrivas ut från en sträng, eller antalet siffror efter decimalpunkten för ett flytande punktvärde, eller det minsta antalet siffror för ett heltal. Dessa skiljer sig mellan ett kort och ett heltal, respektive, och är allmänt bara nödvändiga för datorprogrammering. Konverteringspersonerna själva, som berättar för vilken typ av argument som förväntas, är följande: Observera att printf kräver antalet omvandlingssträngar för att matcha antalet ARGUMENT s som kartlägger dem en-till-en och förväntar sig att hitta exakt en ARGUMENT för varje konverteringssträng. Det enda undantaget är en konverteringssträng som använder en stjärna, så strängar kräver två argument vardera. Konverteringssträngar tolkas alltid från vänster till höger. Följande utskriftskommando: Producerar följande utmatning: Tolkade avvikande teckenuppsättningar Följande teckensekvenser tolkas som specialtecken genom printf: skriver ut en dubbelkvot () skriver ut en backslash () utfärdar en varning (spelar en klocka) utskrifter en backspace instruerar printf för att inte producera ytterligare utmatningsutskrifter, en flyktig (ASCII-kod 27) skriver ut en horisontell flik, skriver en vertikal flik, skriver en byte med oktalt värde NNN (1 till 3 siffror) skriver ut en byte med hexadecinalvärde HH (1 till 2 siffror) skriver ut unicode-tecknet med hexadecimalt värde HHHH (4 siffror) skriver ut unicode-tecknet med hexadecimalt värde HHHHHHHH (8 siffror) skrivs ut ARGUMENT som en sträng med utrymningar som tolkas enligt ovan, med undantag för att oktalavbrott tar formen 0 eller 0 NN Quoting In The Shell Var försiktig med hur ditt skal tolkar citerade strängar. Om ditt skal inte tolkar din citerade sträng korrekt, försök använda enkla citat i stället för dubbla citat. printf exempel Skriver ut följande utmatning: Skriver ut samma utgång som ovanstående exempel. Skriver ut en sträng som berättar platsen för din hemkatalog. Relaterade kommandon awk mdash Interpreter för AWK textbehandling programmeringsspråk. bc mdash En räknare. echo mdash Output text.
No comments:
Post a Comment