GNU/Linux >> Belajar Linux >  >> Linux

Ekstrak jalur yang hilang dari bash array jalur

Anda telah menemukan alasan langsung kode Anda tidak melakukan apa yang Anda harapkan:kesalahan dari ls dilaporkan ke stderr (seperti yang disarankan oleh POSIX), yang tidak ditangkap sebagai masukan oleh pipa. Oleh karena itu, Anda mendapatkan campuran keluaran normal (yang diteruskan tanpa perubahan oleh sed Anda pernyataan) dan stderr (yang melewatinya). Saya tidak tahu mengapa ls Anda keluaran berubah di antara panggilan; mengarahkan stdout ke /dev/null harus memiliki efek menghapus semua "normal" (jalur yang ada) dari output. Perbaikan untuk ini tidak untuk mendorong stderr ke stdout.

Pasca-pemrosesan output dari ls adalah ide yang berbahaya jika Anda menginginkan skrip yang andal. Satu artikel bagus tentang topik ini adalah "Mengapa Anda tidak mengurai keluaran ls(1)", tersedia di situs wooledge.org. Satu T/J mendalam di situs Unix &Linux membahas beberapa masalah:Mengapa tidak parsing ls (dan apa yang harus dilakukan sebagai gantinya)?. Hasilnya adalah bahwa nama file UNIX dapat berisi hampir semua karakter, termasuk spasi, tab, baris baru, tanda kutip tunggal, tanda kutip ganda, tanda kutip tunggal yang lolos, dll! Untuk beberapa contoh singkat, pertimbangkan direktori dengan nama berikut, yang semuanya legal:

  • "Tidak ada file seperti itu" (mkdir "No such file" )
  • "ls:tidak dapat mengakses 'foo':Tidak ada file atau direktori seperti itu" (mkdir "ls: cannot access 'foo': No such file or directory" )
  • "direktori

    dengan

    tertanam

    baris baru" (mkdir $'directory\nwith\nembedded\newlines' )

Yang pertama adalah direktori tidak bersalah yang ditangkap secara salah (dari stdout) oleh grep . Yang kedua juga ditangkap secara salah, tetapi kemudian dirusak lebih lanjut menjadi jalur yang sama sekali berbeda -- yang mungkin ada atau tidak ada! -- oleh sed pernyataan. Yang ketiga adalah salah satu contoh dari apa yang terjadi ketika Anda meneruskan output dari ls ke dalam program berorientasi garis; jika direktori tidak ada, ls akan mengatakannya lebih dari satu baris, yang mungkin merupakan cara Anda mendapatkan dua sed terpisah pernyataan!

Untuk membedakan "jalur yang baik" -- yang ada dan dapat dibaca -- dari "jalur yang buruk", saya menyarankan untuk mengulang larik dan membuat larik baru dari masing-masing.

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

Anda kemudian dapat melakukan apa pun yang Anda suka dengan setiap set:

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

Linux
  1. Cara Terbaik Mendeteksi (dari Skrip) Apakah Perangkat Lunak Sudah Diinstal?

  2. Bagaimana Cara Membuat Array Elemen Unik Dari String/array Di Bash?

  3. Apakah Mungkin Di Bash, Untuk Mulai Membaca File Dari Offset Hitungan Byte Sewenang-wenang?

  1. memulai apachectl dari bash

  2. Bagaimana saya bisa mendapatkan nilai unik dari array di Bash?

  3. Skrip bash Linux untuk mengekstrak alamat IP

  1. Terminal mana yang lebih baik:Bash vs Zsh

  2. Fitur Apa Yang Ada Di Zsh Dan Hilang Dari Bash, Atau Sebaliknya?

  3. Bagaimana cara mengekstrak nama file tanpa ekstensi dari path lengkap?