GNU/Linux >> Znalost Linux >  >> Linux

Extrahujte chybějící cesty z bashového pole cest

Již jste zjistili bezprostřední důvod, proč váš kód nedělal to, co jste očekávali:chyby z ls jsou hlášeny do stderr (jak navrhuje POSIX), který není zachycen jako vstup roura. Získali jste tedy směs normálního výstupu (který prošel beze změny vaším sed příkazy) a stderr (který je obešel). Nevím, proč máte ls výstup se změnil mezi hovory; přesměrování stdout na /dev/null by mělo mít za následek odstranění všech "normálních" (existujících cest) z výstupu. Oprava tohoto problému není strčit stderr do stdout.

Následné zpracování výstupu z ls je nebezpečný nápad, pokud chcete spolehlivý skript. Jeden dobrý článek na toto téma je „Proč byste neměli analyzovat výstup ls(1)“, dostupný na webu wooledge.org. Jedna hloubková otázka/odpověď na webu Unix &Linux se zabývá některými problémy:Proč ne analyzovat ls (a co dělat místo toho)?. Výsledkem je, že názvy souborů UNIX mohou obsahovat téměř jakýkoli znak, včetně mezer, tabulátorů, nových řádků, jednoduchých uvozovek, dvojitých uvozovek, uvozovek s uvozovkami atd.! Pro několik rychlých příkladů zvažte adresáře s těmito názvy, z nichž všechny jsou naprosto legální:

  • "Žádný takový soubor" (mkdir "No such file" )
  • "ls:nemůže získat přístup k 'foo':Žádný takový soubor nebo adresář" (mkdir "ls: cannot access 'foo': No such file or directory" )
  • "adresář

    s

    vložené

    nové řádky" (mkdir $'directory\nwith\nembedded\newlines' )

První je nevinný adresář, který je nesprávně zachycen (ze stdout) grep . Druhá je také neprávem zachycena, ale pak dále zmačkaná do úplně jiné cesty -- který může a nemusí existovat! -- podle sed prohlášení. Třetí je jeden příklad toho, co se stane, když předáte výstup ls do linkově orientovaných programů; pokud adresář neexistuje, ls řekne to na více než jednom řádku, což je pravděpodobně způsob, jakým jste skončili se dvěma samostatnými sed prohlášení!

Abych odlišil „dobré cesty“ – ty, které existují a jsou čitelné – od „špatných cest“, navrhoval bych zacyklení pole a vytvoření nových polí pro každou z nich.

for p in "${paths[@]}"
do
  if [ -r "$p" ]
  then
    goodpaths+=("$p")
  else
    badpaths+=("$p")
  fi
done

S každou sadou si pak můžete dělat, co chcete:

printf 'Good path: -->%s<--\n' "${goodpaths[@]}"
echo
printf 'Bad path: -->%s<--\n' "${badpaths[@]}"

Linux
  1. Jaké funkce jsou v Zsh a chybí Bash, nebo naopak?

  2. Nejlepší způsob, jak zjistit (ze skriptu), zda je software nainstalován?

  3. Je možné v Bash začít číst soubor z libovolného offsetu počtu bajtů?

  1. Spusťte bash skript z adresy URL

  2. extrahovat průměrný čas z ping -c

  3. Jak mohu získat jedinečné hodnoty z pole v Bash?

  1. Který terminál je lepší:Bash vs Zsh

  2. Analyzovat jedno pole z pole Json do pole Bash?

  3. Převeďte textový řetězec v bash na pole