Kommentit
- En ole samaa mieltä siitä, että tämä olisi kaksoiskappale. Hyväksytty vastaus vastaa siihen, miten tiedostojen nimiä voidaan lisätä välilyöntein; sillä ei ole mitään tekemistä " kanssa, miksi etsintää löydetään ' -lähtöjen huonosta käytännöstä ". Löysin tämän kysymyksen (ei toisen), koska minun on lisättävä tiedostojen nimiä välilyönneillä, kuten: tiedostolle $ LIST_OF_FILES; tee … missä $ LIST_OF_FILES ei ole haun tulos; se ' on vain luettelo tiedostonimistä (erotettu uudella rivillä).
- @CarloWood – tiedostonimet voivat sisältää uusia rivejä, joten kysymyksesi on melko ainutlaatuinen: luettelo tiedostonimistä, jotka voivat sisältää välilyöntejä, mutta eivät rivinvaihtoehtoja. Luulen, että ' joudut käyttämään IFS-tekniikkaa osoittaaksesi, että katkos tapahtuu ' \ n '
- @ Diagonwoah, en koskaan tajunnut, että tiedostojen nimissä saa olla uusia rivejä. Käytän pääosin (vain) linux / UNIXia ja jopa välilyönnit ovat harvinaisia; En todellakaan koskaan elämässäni nähnyt uusien rivien käyttöä: s. He saattavat myös kieltää tämän imhon.
- @CarloWood – tiedostonimet päättyvät nollaan (' \ 0 ' , sama kuin ' '). Kaikki muu on hyväksyttävää.
- @CarloWood Sinun on muistettava, että ihmiset äänestävät ensin ja lukevat toisena …
Vastaa
Lyhyt vastaus (lähinnä vastaustasi, mutta käsittelee välilyöntejä)
OIFS="$IFS" IFS=$"\n" for file in `find . -type f -name "*.csv"` do echo "file = $file" diff "$file" "/some/other/path/$file" read line done IFS="$OIFS"
Parempi vastaus (käsittelee myös jokerimerkkejä ja uusia viivoja tiedostonimissä)
find . -type f -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done
Paras vastaus (perustuu Gillesiin ” vastaus )
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";"
Tai vielä parempi, jotta vältetään yhden tiedostoa kohden:
find . -type f -name "*.csv" -exec sh -c " for file do echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty done " exec-sh {} +
Pitkä vastaus
Sinulla on kolme ongelmaa:
- Oletusarvon mukaan kuori jakaa komennon lähdön välilyönteihin, välilehtiin ja uusiin viivoihin
- Tiedostonimet voivat sisältää jokerimerkkejä, jotka laajenisi
- Entä jos on hakemisto, jonka nimi päättyy
*.csv
?
1. Jakaminen vain uudelle riville
Saadaksesi selville, mihin file
asetetaan, kuoren on otettava tulos find
ja tulkita se jotenkin, muuten file
olisi vain koko find
.
Kuori lukee muuttujan IFS
, joka on oletusarvoisesti <space><tab><newline>
.
Sitten se tarkastelee kutakin merkkiä find
-lähdössä. Heti kun se huomaa minkä tahansa merkin, joka on ”s” IFS
, se ajattelee, että se merkitsee tiedostonimen loppua, joten se asettaa file
mihin tahansa merkkeihin, jotka se on nähnyt tähän asti ja suorittaa silmukan. Sitten se alkaa siitä, mihin se jäi, saadakseen seuraavan tiedoston nimen, ja suorittaa seuraavan silmukan jne., kunnes se saavuttaa lopputuloksen. Joten se tekee tämän tehokkaasti:
for file in "zquery" "-" "abc" ...
Jos haluat käskeä jakamaan syötteen vain uusilla rivillä, sinun on tehtävä
IFS=$"\n"
ennen komentoa for ... find
.
Tämä asettaa IFS
arvoksi yksi uusi rivi, joten se jakautuu vain uusille viivoille eikä välilyönneille ja sarkaimille.
Jos käytät sh
tai dash
ksh93
, bash
tai zsh
sijaan sinun on kirjoitettava IFS=$"\n"
näin: näin:
IFS=" "
Se todennäköisesti riittää saadaksesi komentosarjosi toimimaan, mutta jos olet kiinnostunut käsittelemään joitain muita kulmatapauksia oikein, lue eteenpäin … Laajentaminen $file
ilman jokerimerkkejä
Silmukan sisällä missä teet
diff $file /some/other/path/$file
kuori yrittää laajentaa $file
(uudelleen!).
Se voi sisältää välilyöntejä, mutta koska olemme jo asettaneet IFS
yllä, se ei tule olemaan ongelma tässä.
Mutta se voi sisältää myös jokerimerkkejä, kuten *
tai ?
, mikä johtaisi arvaamattomaan toimintaan. (Kiitos Gillesille tämän osoittamisesta.)
Jos haluat kertoa, että kuori ei laajenna jokerimerkkejä, laita muuttuja lainausmerkkien sisään, esim.
diff "$file" "/some/other/path/$file"
Sama ongelma voi myös purra meitä
for file in `find . -name "*.csv"`
Esimerkiksi, jos sinulla on nämä kolme tiedostoa
file1.csv file2.csv *.csv
(erittäin epätodennäköinen, mutta silti mahdollista)
Se olisi kuin olisit juossut
for file in file1.csv file2.csv *.csv
joka laajennetaan muotoon
for file in file1.csv file2.csv *.csv file1.csv file2.csv
aiheuttaen file1.csv
ja file2.csv
käsiteltävä kahdesti.
Sen sijaan meidän on tehtävä
find . -name "*.csv" -print | while IFS= read -r file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty done
read
lukee rivejä vakiosyötteestä, jakaa rivin sanoiksi IFS
mukaan ja tallentaa ne määrittelemiisi muuttujien nimiin.
Tässä kerromme sille uudelleen olla jakamatta riviä sanoiksi ja tallentamaan viiva kansioon $file
.
Huomaa myös, että on muuttunut muotoon read line </dev/tty
.
Tämä johtuu siitä, että silmukan sisällä vakiotulo tulee osoitteesta find
putkilinjan kautta.
Jos teimme juuri read
, se kuluttaa osan nimestä tai kokonaan, ja jotkut tiedostot ohitetaan .
/dev/tty
on pääte, josta käyttäjä suorittaa komentosarjaa. Huomaa, että tämä aiheuttaa virheen, jos komentosarja suoritetaan cronin kautta, mutta oletan, että tällä ei ole merkitystä tässä tapauksessa.
Entä jos tiedoston nimi sisältää uusia rivejä?
Voimme hoitaa sen muuttamalla -print
muotoon -print0
ja käyttämällä read -d ""
pipeline:
find . -name "*.csv" -print0 | while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read char </dev/tty done
Tämä tekee find
nollatavun jokaisen tiedoston nimen loppuun. Nollatavut ovat ainoat merkit, joita ei sallita tiedostojen nimissä, joten tämän pitäisi käsitellä kaikkia mahdollisia tiedostojen nimiä, riippumatta siitä kuinka outoa.
Saadaksesi tiedostonimen toiselle puolelle käytämme IFS= read -r -d ""
.
Missä käytimme yllä read
, käytimme uuden rivin oletusarvoista erotinta, mutta nyt, find
käyttää nollaa rivinrajoittajana. Kohdassa bash
ei voi ”siirtää NUL-merkkiä argumentissa komennolle (jopa sisäänrakennetuille), mutta bash
ymmärtää -d ""
merkityksellä NUL erotettu . Joten käytämme -d ""
tehdäksesi read
käytä samaa rivinrajoitinta kuin find
. Huomaa, että -d $"\0"
toimii myös, koska bash
joka ei tue NUL-tavuja, sitä pidetään tyhjänä merkkijonona.
Oikeudenmukaisuuden lisäämiseksi lisätään myös -r
, jonka mukaan älä käsittele paluuviivoja tiedostojen nimet. Esimerkiksi ilman -r
poistetaan \<newline>
ja \n
muunnetaan muotoon n
.
Kannettavampi tapa kirjoittaa tämä, joka ei vaadi bash
tai zsh
tai muistat kaikki yllä olevat tavut nollatavuista (jälleen Gillesin ansiosta):
find . -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read char </dev/tty " exec-sh {} ";"
* 3. Ohitetaan hakemistot, joiden nimet päättyvät .csv
find . -name "*.csv"
vastaavat myös hakemistoja, joita kutsutaan nimellä something.csv
.
Tämän välttämiseksi lisää -type f
komentoon find
.
find . -type f -name "*.csv" -exec sh -c " file="$0" echo "$file" diff "$file" "/some/other/path/$file" read line </dev/tty " exec-sh {} ";"
Kuten glenn jackman huomauttaa, kummassakin näistä esimerkeistä jokaiselle tiedostolle suoritettavat komennot ovat suoritetaan alikuoressa, joten jos muutat muuttujia silmukan sisällä, ne unohdetaan.
Jos sinun on asetettava muuttujia ja annettava ne edelleen silmukan lopussa voit kirjoittaa sen uudestaan käyttämään prosessin korvaamista näin:
i=0 while IFS= read -r -d "" file; do echo "file = $file" diff "$file" "/some/other/path/$file" read line </dev/tty i=$((i+1)) done < <(find . -type f -name "*.csv" -print0) echo "$i files processed"
Huomaa, että jos yrität kopioida ja liittää tämän komentoriville , read line
kuluttaa echo "$i files processed"
, joten komentoa ei suoriteta.
Tämän välttämiseksi sinun on voisi poistaa read line </dev/tty
ja lähettää tuloksen hakulaitteelle, kuten less
.
HUOMAUTUKSET
Poistin puolipisteet (;
) silmukka. Voit laittaa ne takaisin, jos haluat, mutta niitä ei tarvita.
Nykyään $(command)
on yleisempi kuin `command`
. Tämä johtuu pääasiassa siitä, että sen kirjoittaminen $(command1 $(command2))
on helpompaa kuin `command1 \`command2\``
.
read char
ei oikeastaan lue merkkiä.Se lukee kokonaisen rivin, joten muutin sen muotoon read line
.
Kommentit
-
while
putkessa voi aiheuttaa ongelmia luotuun alikuoreen (silmukkalohkon muuttujia ei näy esimerkiksi komennon valmistuttua). Bashilla käytän syötteen uudelleenohjausta ja prosessin korvaamista:while read -r -d $'\0' file; do ...; done < <(find ... -print0)
- Toki tai käyttämällä heredokia:
while read; do; done <<EOF "$(find)" EOF
. Ei kuitenkaan niin helppo lukea. - @glenn jackman: Yritin lisätä selitystä juuri nyt. Teinkö siitä vain paremman vai huonomman?
- Et tarvitse ' et tarvitse
IFS, -print0, while
jaread
jos käsittelet kokonaisuudessaanfind
, kuten alla oleva ratkaisu osoittaa. - Ensimmäinen ratkaisusi selviää kaikista hahmoista paitsi uudesta rivistä jos poistat myös huijaamisen käytöstä
set -f
.
Vastaa
Tämä komentosarja epäonnistuu, jos jokin tiedostonimi sisältää välilyöntejä tai kuori-merkkejä \[?*
. find
-komento antaa yhden tiedostonimen riviä kohden. Sitten komento substituutio `find …`
arvioidaan kuoren avulla seuraavasti:
- Suorita komento
find
, tartu sen tulokseen. - Jaa
find
-lähtö erillisiksi sanoiksi. Kaikki välilyönnit ovat sanan erottimia. - Laajenna jokaisen sanan kohdalla vastaavien tiedostojen luetteloon jokaisen sanan kohdalla.
Esimerkiksi Oletetaan, että nykyisessä hakemistossa on kolme tiedostoa, nimeltään `foo* bar.csv
, foo 1.txt
ja foo 2.txt
.
-
find
-komento palauttaa./foo* bar.csv
. - Kuori jakaa tämän merkkijonon välilyönnissä tuottamalla kaksi sanaa:
./foo*
jabar.csv
. - Koska
./foo*
sisältää huijaavan metahakemiston, se laajennetaan vastaavien tiedostojen luetteloon:./foo 1.txt
ja./foo 2.txt
. - Siksi
for
-silmukka suoritetaan peräkkäin./foo 1.txt
,./foo 2.txt
jabar.csv
.
Voit välttää useimmat ongelmat tässä vaiheessa vähentämällä sanojen jakamista ja kääntämistä harhautusta. Voit vähentää sanan jakamista asettamalla muuttujan IFS
yhdeksi uudeksi riviksi; tällä tavalla find
-lähtö jaetaan vain uusilla viivoilla ja välilyöntejä jää. Poista huijaaminen käytöstä suorittamalla set -f
. Sitten tämä koodin osa toimii niin kauan kuin mikään tiedostonimi ei sisällä uuden rivin merkkiä.
IFS=" " set -f for file in $(find . -name "*.csv"); do …
(Tämä ei ole osa ongelmasi, mutta minä suosittele $(…)
-kohdan käyttöä `…`
-kohdassa. Niillä on sama merkitys, mutta backote-versiossa on outoja lainaussääntöjä.)
Alla on toinen ongelma: diff $file /some/other/path/$file
pitäisi olla
diff "$file" "/some/other/path/$file"
Muussa tapauksessa $file
jaetaan sanoiksi ja sanoja käsitellään globaaleina, kuten yllä olevalla komennolla substitutio. Jos sinun on muistettava yksi asia shell-ohjelmoinnista, muista tämä: käytä aina lainausmerkkejä muuttujien laajennusten ($foo
) ja komentojen korvausten ( $(bar)
) , ellet tiedä, että haluat jakaa. (Yllä, tiesimme, että halusimme jakaa find
-lähdön riveihin.)
Luotettava tapa kutsua find
käskee suorittamaan komennon jokaiselle löydetylle tiedostolle:
find . -name "*.csv" -exec sh -c " echo "$0" diff "$0" "/some/other/path/$0" " {} ";"
Tässä tapauksessa toinen tapa on verrata kahta hakemistoa, vaikka sinun on sulje pois kaikki ”tylsät” tiedostot.
diff -r -x "*.txt" -x "*.ods" -x "*.pdf" … . /some/other/path
Kommentit
- I ' d unohti jokerimerkit toisena syynä lainata oikein. Kiitos! 🙂
-
find -exec sh -c 'cmd 1; cmd 2' ";"
-kohdan sijaan sinun on käytettäväfind -exec cmd 1 {} ";" -exec cmd 2 {} ";"
, koska kuoren on peitettävä parametrit, mutta ei löydä ' t. Tässä erityistapauksessa echo " $ 0 " ei tarvitse olla ' t oltava osa komentosarjaa, liitä vain -print';'
: n jälkeen. ' et sisällyttänyt kysymystä jatkaaksesi, mutta jopa se voidaan tehdä löytämällä, kuten alla oleva sieluni osoittaa. 😉 - @userunknown: Kohteen
{}
käyttö parametrin alijononafind -exec
-palvelussa ei ole kannettava, että ' syy kuorelle.En ymmärrä ' en ymmärrä mitä tarkoitat sanalla ”komentotulkin on peitettävä parametrit”; jos ' on kyse lainaamisesta, ratkaisuni on lainattu oikein. ' on oikeassa siinä, ettäecho
-osan voisi suorittaa-print
.-okdir
on melko uusi GNU-hakulaajennus, se ' ei ole käytettävissä kaikkialla. En sisällyttänyt ' etenemisen odottamista, koska mielestäni erittäin huono käyttöliittymä ja kysyjä voivat helposti laittaaread
kuorenpätkään, jos hän haluaa. - Lainaus on eräänlainen naamiointi, eikö ' ole sitä? En ymmärrä ' huomautustasi siitä, mikä on kannettavaa ja mikä ei. Esimerkki (toinen alhaalta) käyttää -exec -ohjelmaa kutsumaan
sh
ja käyttää{}
– joten missä esimerkkini on (-okdir vieressä) vähemmän kannettava?find . -name "*.csv" -exec diff {} /some/other/path/{} ";" -print
- ”Peittäminen” ei ole ' t yleistä terminologiaa kuorikirjallisuudessa, joten ' Minun on selitettävä, mitä tarkoitat, jos haluat tulla ymmärrettäväksi. Esimerkkini käyttää
{}
vain kerran ja erillisessä argumentissa; muut tapaukset (käytetään kahdesti tai alaryhmänä) eivät ole kannettavia. ”Kannettava” tarkoittaa, että se ' toimii kaikissa unix-järjestelmissä; hyvä ohje on POSIX / Single Unix -määritys .
vastaus
Olen yllättynyt siitä, että en näe readarray
mainintaa. Se tekee tämän erittäin helpoksi, kun sitä käytetään yhdessä <<<
operaattori:
$ touch oneword "two words" $ readarray -t files <<<"$(ls)" $ for file in "${files[@]}"; do echo "|$file|"; done |oneword| |two words|
<<<"$expansion"
-rakenteen avulla voit myös jakaa muuttujat, jotka sisältävät uudet rivit taulukoiksi, kuten :
$ string=$(dmesg) $ readarray -t lines <<<"$string" $ echo "${lines[0]}" [ 0.000000] Initializing cgroup subsys cpuset
readarray
on ollut Bashissa jo vuosia, joten tämän pitäisi todennäköisesti olla kanoninen tapa tehdä tämä Bashissa.
Vastaa
Afaik-löydössä on kaikki mitä tarvitset.
find . -okdir diff {} /some/other/path/{} ";"
find huolehtii itse ohjelmien soittamisesta. -okdir kehottaa sinua ennen diff-tiedostoa (oletko varma, että kyllä / ei).
Ei kuorta, ei huijausta, jokereita, pi, pa, po.
Sidenote: Jos yhdistät haun kanssa for / while / do / xargs, useimmissa tapauksissa y teet sen väärin. 🙂
Kommentit
- Kiitos vastauksesta. Miksi teet sen väärin, jos yhdistät haun hakemistoon for / while / do / xargs?
- Löydä jo iteraatiot tiedostojen osajoukon yli. Useimmat kysymyksiin ilmestyvät ihmiset voisivat käyttää vain yhtä toimintoa (-ok (dir) -exec (dir), -delete) yhdessä "; " tai + (myöhemmin rinnakkaista kutsua varten). Tärkein syy siihen on, että sinun ' ei tarvitse hämmentää tiedostoparametreja, peittäen ne kuorelle. Ei niin tärkeä: Sinun ei tarvitse ' uusia prosesseja koko ajan, vähemmän muistia, enemmän nopeutta. lyhyempi ohjelma.
- Ei täällä henkesi murskaamiseksi, mutta vertaa:
time find -type f -exec cat "{}" \;
kohteeseentime find -type f -print0 | xargs -0 -I stuff cat stuff
.xargs
-versio oli nopeampi 11 sekunnilla käsiteltäessä 10000 tyhjää tiedostoa. Ole varovainen, kun väität, että useimmissa tapauksissafind
: n yhdistäminen muihin apuohjelmiin on väärin.-print0
ja-0
on tarkoitus käsitellä tiedostojen nimissä olevia välilyöntejä käyttämällä nollatavua alkioerottimena välilyönnin sijasta. - @JonathanKomar: Find / exec -komento kesti järjestelmässäni 11,7 s 10 000 tiedostolla, xargs-versio 9,7 s,
time find -type f -exec cat {} +
, kuten edellisessä kommentissani ehdotettiin, kesti 0,1 s. Huomaa, että " on väärä " ja " sinun ' tekee sen väärin ", varsinkin kun hymiö on koristeltu. Teitkö esimerkiksi väärin? 😉 BTW, tiedostonimen välilyönnit eivät ole ongelma yllä olevalle komennolle, ja ne löytävät yleensä. Rahtikultin ohjelmoija? Ja muuten, löydön yhdistäminen muihin työkaluihin on hienoa, vain xargs on suurimman osan ajasta superflous. - @userunknown Selitin, kuinka koodini käsittelee tilaa jälkipolville (tulevien katsojien koulutus), ja ei tarkoita, että koodisi ei. Rinnakkaispuheluiden
+
on erittäin nopea, kuten mainitsit. En sanoisi lastikulttuurin ohjelmoijaa, koska tämä kyky käyttääxargs
tällä tavalla on kätevä monissa tilanteissa. Olen enemmän samaa mieltä Unixin filosofian kanssa: tee yksi asia ja tee se hyvin (käytä ohjelmia erikseen tai yhdessä työn saamiseksi).find
kävelee siellä hienoa viivaa.
Vastaa
Selaa kaikkia tiedostoja ( kaikki erikoismerkit mukaan lukien) täysin turvallinen etsintä (katso linkki ohjeista):
exec 9< <( find "$absolute_dir_path" -type f -print0 ) while IFS= read -r -d "" -u 9 do file_path="$(readlink -fn -- "$REPLY"; echo x)" file_path="${file_path%x}" echo "START${file_path}END" done
Kommentit
- Kiitos, että mainitsit
-d ''
. En ymmärtänyt, että ' ei ymmärtänyt, että$'\0'
oli sama kuin''
, mutta näyttää siltä olla. Hyvä ratkaisu. - Pidän haun irrotuksesta ja kiitos.
Vastaa
Olen yllättynyt, kukaan ei vielä maininnut ilmeistä ratkaisua zsh
:
for file (**/*.csv(ND.)) { do-something-with $file }
((D)
sisällyttämään myös piilotetut tiedostot, (N)
virheen välttämiseksi, jos vastaavuuksia ei ole, (.)
rajoittaa tavallisiin tiedostoihin.)
bash4.3
ja uudemmat tukevat sitä nyt myös osittain:
shopt -s globstar nullglob dotglob for file in **/*.csv; do [ -f "$file" ] || continue [ -L "$file" ] && continue do-something-with "$file" done
vastaus
Tiedostojen nimet, joissa on välilyöntejä, näyttävät komentoriviltä useilta nimiltä, jos ne ” Jos tiedostosi on nimetty ”Hello World.txt”, diff-rivi laajenee muotoon:
diff Hello World.txt /some/other/path/Hello World.txt
joka näyttää neljältä tiedostonimeltä. Laita vain lainauksia argumenttien ympärillä:
diff "$file" "/some/other/path/$file"
Kommentit
- Tämä auttaa, mutta ei ' ei ratkaise ongelmaa. Näen edelleen tapauksia, joissa tiedosto on jaettu useisiin tunnuksiin.
- Tämä vastaus on harhaanjohtava. Ongelma on komento
for file in `find . -name "*.csv"`
. Jos tiedostoa onHello World.csv
,file
asetetaan arvoon./Hello
jaWorld.csv
. Lainaamalla$file
ei voitu ' apua.
Vastaa
Kaksoislainaus on ystäväsi.
diff "$file" "/some/other/path/$file"
Muuten muuttujan sisältö jakautuu sanaan.
Kommentit
- Tämä on harhaanjohtavaa. Ongelma on komento
for file in `find . -name "*.csv"`
. Jos tiedostossa onHello World.csv
,file
asetetaan arvoon./Hello
ja sitten arvoonWorld.csv
. Lainaus$file
ei saanut apua '.
Vastaa
Bash4: n avulla voit myös käyttää sisäänrakennettua mapfile-toimintoa asettamaan taulukon, joka sisältää kukin rivi, ja iteroida tällä taulukolla.
$ tree . ├── a │ ├── a 1 │ └── a 2 ├── b │ ├── b 1 │ └── b 2 └── c ├── c 1 └── c 2 3 directories, 6 files $ mapfile -t files < <(find -type f) $ for file in "${files[@]}"; do > echo "file: $file" > done file: ./a/a 2 file: ./a/a 1 file: ./b/b 2 file: ./b/b 1 file: ./c/c 2 file: ./c/c 1
vastaus
Arvojen välilyönnit voidaan välttää yksinkertaisesti silmukkarakenteelle
for CHECK_STR in `ls -l /root/somedir` do echo "CHECKSTR $CHECK_STR" done
ls-root / somedir c säilyttää tiedostoni välilyönneillä
Tiedostoni yläpuolella oleva välilyönti
tämän tulostuksen välttämiseksi, yksinkertainen ratkaisu (huomioi lainausmerkit)
for CHECK_STR in "`ls -l /root/somedir`" do echo "CHECKSTR $CHECK_STR" done
tuota tiedostoni välilyönteillä
yritetty bashilla
Kommentit
- ”Tiedostojen selaus ”- niin kysymys sanoo. Ratkaisusi tuottaa koko
ls -l
tuotoksen kerralla . Se on käytännössä samanlainen kuinecho "CHECKSTR `ls -l /root/somedir`"
.