Fórum Root.cz
Hlavní témata => Software => Téma založeno: mikesznovu 16. 09. 2024, 13:16:11
-
Dotazy na zvláštnost xargs (ntice argumentů v 1 příkazu)Mám pár otázek na pokročilé použití xargs.
0. Je potřeba příkazu předávat pseudoargument "--", nebo pozná, že příkaz začal sám chytře ? Tedy že když narazí na ne-přepínač, odtudu to bere jako příkaz (příklad : xargs bash -c -d 2)
1. Jak docílit, aby se příkazu předala n-tice argumentů? Zde to mám okatě simulované přes bash -c seq 13 |xargs -I g bash -c "printf '(
%s) .%s. (%s) ,\n' g h g"
vypíše (1) .h. (1) ,(2) .h. (2),... . Já ale chci vypsat : 1 h 2 , 3 h 4, 5 h 6 ,......
2: Proč se vypisuje toto:
seq 13 |xargs \
printf '(%s) (%s) ,\n' {} {} #end
({}) ({}) , # <<<< Tento první řádek výstupu
(1) (2) ,
(3) (4) ,
(5) (6) ,
(7) (8) ,
(9) (10) ,
(11) (12) ,
(13) () ,
, zatímco bez -i je to ok.
3. Nějakým zázrakem bod 1. se dá splnit tím ,že xargsu předám rovnou printf přímo, bez obalení bashem
seq 13 |xargs \
printf '(%s) (%s) ,\n' #end
(1) (2) ,
(3) (4) ,
(5) (6) ,
(7) (8) ,
(9) (10) ,
(11) (12) ,
(13) () ,
4. Jak je možné, že xargs pozná vhodný počet argumentů?
seq 13 |xargs \
printf '(%s) (%s) (%s) (%s) ,\n' #ende
(1) (2) (3) (4) ,
(5) (6) (7) (8) ,
(9) (10) (11) (12) ,
(13) () () () ,
5,. proč tedy xaegs automaticky nepozná délku? Jsou tam prázné závorky.
seq 13 |xargs -i printf '(%s) (%s)
(%s) (%s) ,\n' {} {} #en
(1) (1) () () ,
(2) (2) () () ,
(3) (3) () () ,
(4) (4) () () ,
(5) (5) () () ,
(6) (6) () () ,
(7) (7) () () ,
(8) (8) () () ,
(9) (9) () () ,
(10) (10) () () ,
(11) (11) () () ,
(12) (12) () () ,
(13) (13) () () ,d
6. Tohle přirozeně nepůjde
seq 13 |xargs \
bash -c printf '(%s) (%s) ,\n'
printf: užití: printf [-v proměnná] formát [argumenty
Tedy :
jak doplnit ty argument po n-ticích i do příkazu s placeholderem? (Třeba protože chci volat třeba exotický příkaz brambora.py -a param_sudy -arg2=3 paramlichy), kde nemohu shufflovat pořadí
Proč někdy autodetekuje správný počet argumentů ? (1 2 3 4 .... 5 6 7 8)
A jak zařídit korektní předání argumentů v případě bash -c ' něcoskript.py {} x {}'
A proč použití -i + {} (nebo -I a symbolu) pokazí předávání n-tic
četl jsem v manu, že xargs nějak spouští měně invokcí než je potřeba, kvůli výkonu. To by mi ale vysvětlovalo jen ten problém kdy nepoužívám -i / -I g ve varientě bash -c vs plain ...... (druhý odstavec ... There will be many fewer invocations...)
Díky za osvětlení
(mimochodem, opět se stala lahůdka, že po odeslání se ukázalo, Litujeme, přístup byl odepřen. + při přihlášení v druhém tabu a návratu do prvního jsem dal REload+post , ale to vrací "Litujeme, formulář jste asi už odeslali". To je moc hezké, že to systém ví, . Ale možnost tam si vybrat, že opravdu ho chci poslat ,tam jaksi není)
-
Protoze jste se v tom uplne ztratil. Musite se vratit uplne k zakladu.
$ seq 13 |xargs echo printf '(%s) (%s) ,\n' {} {}
printf (%s) (%s) ,\n {} {} 1 2 3 4 5 6 7 8 9 10 11 12 13
Cili xarg zavola jen `printf (%s) (%s) ,\n {} {} 1 2 3 4 5 6 7 8 9 10 11 12 13` a zbytek necha na bashi, aby si prebral jak chce.
BTW, kde jste vzal ze xargs pouziva by default '{}'? To plati pro (jen) pro `find -exec ...`
-
Jinak
seq 13 |xargs -L2 printf '(%s) (%s) ,\n'
(1) (2) ,
(3) (4) ,
(5) (6) ,
(7) (8) ,
(9) (10) ,
(11) (12) ,
(13) () ,
-
Tyhle věci jsou někdy záludné, ale pomůže si to rozebrat na jednotlivé části, které se dají zkoumat a pochopit jednotlivě.
1) Doporučuji si napsat program/skript, který vypisuje svoje argumenty (https://www.abclinuxu.cz/blog/xkucf03/2016/9/parametry-prikazu-roury-java-a-jine-jazyky) - stačí to v Bashi:
#!/bin/bash
echo "CLI argumenty:"
for ((i=0;i<=$#;i++)); do
echo " argv[$i] = ${!i}"
done;
tenhle skript pak pouštíme na místo jiného programu tam, kde si nejsme jistí, co se děje a jaké argumenty se kam předávají. Pomáhá to vysvětlit případy, kdy nevíme, jestli se nějaký příkaz spustil víckrát s menším počtem argumentů nebo jednou se všemi dohromady, nebo když nevíme, zda a jak se pracuje s hodnotami v uvozovkách a apostrofech.
2) Příkaz printf podporuje více argumentů, než kolik jich bylo zadáno ve formátovacím řetězci - prostě to celé opakuje pořád dokola (těch argumentů by měl být ideálně násobek, ale pokud nějaký chybí, tak je hodnota jen prázdná a taky to projde).
$ printf '%s=%s\n' a b c d
a=b
c=d
$ printf '%s=%s\n' a b c
a=b
c=
-
A potom má v praxi , takovýhle trápení,
který by v funkcionálním skriptu bylo otázkou na 1 map a 1 sprintf(který je dokonce povýšen na operátor) a .filter:
#např:
45 toplist.cz
11 kernel.org
...
[vstup je řetězec s 2 slovy na každém řádku] | xargs -i bash -c \
"echo {} \$(host -tA \$(echo '{}'|cut -f2 -d \ ) |grep -Po address\ \\\K.+ )" \
| grep -v 7
# výstup je , že to na konec řádku přidá resolvovaný záznam domény a vyfiltruje řádky neobsahující číslici 7
45 toplist.cz 123.456.889.13
11 kernel.org 7.1.2.3
Jde mi o to naučit se to v bashi s xargs, je na tohle vhodné? Jde můj příklad přepsat ,aby byl elegenantní a stále v bashi a xargs? Nebo s přímhořením oka nahradit xargs awk. . Nelíbí se mi tam to noření bash -c a ty $() eskapády