Output grep berwarna: Bukan GREP_OPTIONS bukan alias

10

Saya ingin keluaran berwarna grep.

.... Tapi

  • Strategi 1: GREP_OPTIONS. Tapi ini sudah usang. Lihat http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html
  • Stragegy 2: GREP_COLORS terlihat seperti solusi pada pandangan pertama, tetapi ini melakukan sesuatu yang berbeda.
  • Strategi 3: alias. Ini tidak berfungsi find ... | xargs grep, karena xargs tidak mengevaluasi alias.
  • Strategi 4: Tulis skrip pembungkus sederhana. Tidak, saya pikir ini terlalu kotor dan membuat lebih banyak masalah daripada menyelesaikannya.
  • Strategi 5: menambal kode sumber
  • Strategi 6: Hubungi pengembang grep, minta penggantian GREP_OPTIONS
  • Strategi NICE-and-EASY: ... ini tidak ada. Saya tidak tahu.

Bagaimana cara mengatasinya?

Terima kasih telah mencoba membantu!

... tapi aku tidak bisa memberikan hadiahnya

Sebut saya kasar, arogan, menghina, kasar ....

Saya hanya melihat jalan-jalan - tidak ada solusi. Tidak ada jawaban yang memuaskan pertanyaan itu.

Terima kasih untuk usaha Anda.

guettli
sumber
1
Anda telah menolak dua saran untuk menggunakan skrip pembungkus (Strategi 4 Anda) sebagai "bukan jawaban". Bisakah Anda menggambarkan apa yang "kotor", "menyusahkan", atau "tidak benar-benar jawaban" tentang hal itu? Mungkin itu masalah terpisah yang bisa diselesaikan.
JigglyNaga
2
strategi 5 adalah menambal kode sumber dan diatur color_optionke2 ...
don_crissti
2
@JigglyNaga di sini adalah penjelasan saya mengapa skrip wrapper bukan solusi. Tim kami mengelola beberapa server. Kurang dari seribu saat ini, tetapi jumlahnya meningkat. Ya, kami menggunakan manajemen konfigurasi dan akan mudah untuk menggunakan skrip untuk semuanya. Tetapi saya ingin segalanya menjadi mudah dan langsung (pikirkan anggota baru dalam tim. Saya tidak ingin membingungkan mereka). The --colorpilihan sudah memiliki nilai auto. Saya hanya tidak tahu mengapa Anda tidak dapat mengaktifkannya secara default.
guettli
Anda harus menggunakan strategi 4 atau 5 - Saya lebih suka strategi 4 dengan script dash / sh minimal ( exec grep --color=auto "$@"), secara opsional dengan nama yang berbeda ( grepcatau colorgrep). Ini memiliki overhead diabaikan (dan tidak ada proses bersamaan tambahan saat runtime). Alasan Anda menamai mereka "tidak cukup mudah" adalah kenyataan bahwa Anda tidak melihat fitur ini cukup berguna untuk menghabiskan upaya (relatif sedikit) satu kali untuk mengimplementasikannya, dan mencari orang lain untuk melakukannya untuk Anda. Karena itu, komentar "tidak benar-benar jawaban" Anda terhadap jawaban yang diposting cukup kasar.
Nominal Animal
1
@NominalAnimal Ya, Anda benar "tidak benar-benar jawaban" terdengar kasar. Saya bukan penutur asli. Kata-kata mana (mentransfer pesan yang sama) yang lebih baik?
guettli

Jawaban:

13

Beberapa alasan OP menyatakan opsi tidak cocok tidak memiliki dasar dalam kenyataan. Di sini, saya menunjukkan efek seperti apa yang menggunakan strategi OP 4:


Pada sebagian besar distribusi, grepdiinstal dalam /bin(khas) atau /usr/bin(OpenSUSE, mungkin yang lain), dan default PATHberisi /usr/local/binsebelum /binatau /usr/bin. Ini berarti bahwa jika Anda buat /usr/local/bin/grepdengan

#!/bin/sh
exec /bin/grep --color=auto "$@"

di mana /bin/shshell yang kompatibel dengan POSIX disediakan oleh distribusi Anda, biasanya bash atau dash. Jika grepada /usr/bin, maka buatlah itu

#!/bin/sh
exec /usr/bin/grep --color=auto "$@"

Overhead skrip ini minimal. The execpernyataan berarti bahwa penafsir naskah digantikan oleh grepbiner; ini berarti bahwa shell tidak tetap dalam memori saat grepsedang dieksekusi. Dengan demikian, satu-satunya overhead adalah satu eksekusi tambahan dari penerjemah skrip, yaitu latensi kecil dalam waktu jam dinding. Latensi kira-kira konstan (bervariasi hanya tergantung pada apakah grepdan shsudah dalam cache halaman atau tidak, dan pada seberapa banyak bandwidth I / O tersedia), dan tidak tergantung pada berapa lama grepdieksekusi atau berapa banyak data yang diproses.

Jadi, berapa lama latensi itu, yaitu overhead ditambahkan oleh skrip wrapper?

Untuk mengetahuinya, buat skrip di atas, dan jalankan

time /bin/grep --version
time /usr/local/bin/grep --version

Di mesin saya, yang pertama membutuhkan waktu nyata 0,005 (melintasi sejumlah besar berjalan), sedangkan yang terakhir membutuhkan waktu nyata 0,006. Jadi, overhead menggunakan pembungkus pada mesin saya adalah 0,001 (atau kurang) per doa.

Ini tidak signifikan.

Saya juga gagal melihat sesuatu yang "kotor" tentang ini, karena banyak aplikasi dan utilitas umum menggunakan pendekatan yang sama. Untuk melihat daftar seperti itu di mesin Anda di /bindan /usr/bin, jalankan saja

file /bin/* /usr/bin/* | sed -ne 's/:.*shell script.*$//p'

Pada komputer saya, output di atas termasuk egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, dan xfig, yang saya gunakan cukup sering. Kecuali jika Anda menganggap seluruh distribusi Anda "kotor" karena mengandalkan skrip wrapper, Anda tidak punya alasan untuk menganggap skrip wrapper seperti itu "kotor".


Mengenai masalah skrip pembungkus seperti itu dapat menyebabkan:

Jika hanya pengguna manusia (yang bertentangan dengan skrip) yang menggunakan versi grep yang secara default untuk mendukung warna jika output ke terminal, maka skrip wrapper dapat dinamai colorgrepatau cgrepatau apa pun yang sesuai dengan OP.

Ini menghindari semua kemungkinan masalah kompatibilitas, karena perilaku greptidak berubah sama sekali.


Mengaktifkan grepopsi dengan skrip wrapper, tetapi dengan cara yang menghindari masalah baru:

Kami dapat dengan mudah menulis ulang skrip pembungkus untuk mendukung kebiasaan GREP_OPTSmeskipun GREP_OPTIONStidak didukung (karena sudah usang). Dengan cara ini pengguna cukup menambahkan export "GREP_OPTIONS=--color=auto"atau mirip dengan profil mereka. /usr/local/bin/grepkemudian

#!/bin/sh
exec /bin/grep $GREP_OPTIONS "$@"

Perhatikan bahwa tidak ada tanda kutip di sekitar $GREP_OPTIONS, sehingga pengguna dapat menentukan lebih dari satu opsi.

Di sistem saya, mengeksekusi time /usr/local/bin/grep --versiondengan GREP_OPTIONSkosong, atau dengan GREP_OPTIONS=--color=auto, sama cepatnya dengan versi sebelumnya dari skrip wrapper; yaitu, biasanya membutuhkan satu milidetik lebih lama untuk dieksekusi daripada polos grep.

Versi terakhir ini adalah yang saya pribadi sarankan untuk digunakan.


Singkatnya, strategi OP 4:

  • direkomendasikan oleh greppengembang

  • sepele untuk diterapkan (dua baris)

  • memiliki overhead yang tidak signifikan (latensi ekstra satu milidetik per doa pada laptop khusus ini; mudah diverifikasi pada setiap mesin)

  • dapat diimplementasikan sebagai skrip wrapper yang menambahkan GREP_OPTSdukungan (untuk menggantikan yang sudah usang / tidak didukung GREP_OPTIONS)

  • dapat diimplementasikan (sebagai colorgrep/ cgrep) yang tidak mempengaruhi skrip atau pengguna yang ada sama sekali

Karena ini adalah teknik yang sudah banyak digunakan dalam distribusi Linux, itu adalah teknik yang umum dan tidak "kotor".

Jika diimplementasikan sebagai pembungkus terpisah ( colorgrep/ cgrep), itu tidak dapat membuat masalah baru karena tidak mempengaruhi grepperilaku sama sekali. Jika diimplementasikan sebagai skrip wrapper yang menambahkan GREP_OPTSdukungan, menggunakan GREP_OPTS=--color=automemiliki risiko yang sama persis (wrt. Masalah dengan skrip yang ada) yang --color=autoakan ditambahkan default upstream . Dengan demikian, komentar bahwa ini "menciptakan lebih banyak masalah daripada yang dipecahkan" sama sekali tidak benar: tidak ada masalah tambahan yang dibuat.

Hewan Nominal
sumber
3

Dokumentasi yang Anda berikan dengan strategi pertama mengatakan:

Harap gunakan alias atau skrip sebagai gantinya. Misalnya, jika grep ada di direktori '/ usr / bin' Anda dapat menambahkan $ HOME / bin ke PATH Anda dan membuat skrip yang dapat dieksekusi $ HOME / bin / grep yang berisi yang berikut:

#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"

Jadi jika alias tidak mungkin bagi Anda, skrip wrapper adalah satu-satunya cara.

stderr
sumber
Itu Strategi 4 ... bukan jawaban.
guettli
3

Alasan GREP_OPTIONSvariabel itu ditinggalkan adalah bahwa ia cenderung menyebabkan masalah ketika grepdipanggil di suatu tempat dalam skrip dan skrip tidak bekerja dengan opsi alternatif yang berasal dari variabel. Jika Anda menulis skrip pembungkus untuk grepmaka Anda memiliki masalah yang sama, kecuali jika Anda memberikannya nama yang berbeda .

$ cat ~/bin/cgrep
#!/bin/sh
exec grep --color=always "$@"
$ find  -exec cgrep  {} +

Atau, simpan opsi favorit Anda dalam variabel. Dalam shell selain zsh, ini merepotkan jika opsinya berisi karakter wildcard ( \[*?), tetapi sebaliknya Anda bisa menggunakan variabel yang tidak dikutip untuk mendapatkan perintah dengan argumen.

cgrep=(grep --color=always)
find  -exec $cgrep  {} +

Perhatikan bahwa GNU dan BSD grep dapat memproses pohon direktori secara rekursif, yang mengurangi kebutuhan finddalam kombinasi dengan grepsebagian besar waktu.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Itu Strategi 4 ... bukan jawaban.
guettli
@guettli, itu jawaban yang benar. Jika Anda menginginkan perintah dengan perilaku berbeda grep, Anda memerlukan perintah dengan nama berbeda, atau jika Anda tetap menggunakan nama yang sama, Anda akan memecah skrip yang mengharapkan perilaku asli / standar. Itu yang terbersih dan tidak menimbulkan masalah tambahan .
Stéphane Chazelas
@ StéphaneChazelas ya Anda benar. Ini adalah jawaban yang benar menurut sudut pandang Anda.
guettli
1

Cara termudah adalah menggunakan alias (strategi 3). Jika Anda benar-benar peduli dengan xargsperintah tersebut, Anda masih bisa menimpanya dengan fungsi bash.

alias grep='grep --color'
xargs() {
    local args
    for ((i=1; i<=$#; i++))
    do
            if [[ "-E -L -P -I -s -d" == *"${!i}"* ]]; then
                    ((i=i+1))
            elif [[ ${!i:0:1} != "-" ]]; then
                    if [[ ${!i} == "grep" ]]; then
                            args="--color"
                    fi
                    /usr/bin/xargs ${@:1:i} $args ${@:i+1}
                    return;
            fi
    done
}

Tapi ini tidak lebih baik daripada menggunakan perintah wrapper yang tampaknya merupakan solusi yang disarankan oleh greptim:

/usr/local/bin/grep:

#!/bin/bash
/bin/grep --color "$@"

Menurut pendapat saya, Anda harus menghubungi greptim pengembang untuk meminta mereka memberikan pengganti sederhana untuk GREP_OPTIONSvariabel yang akan memungkinkan warna grepsesuai dengan beberapa variabel lingkungan.

Akan sangat sederhana bagi mereka untuk mengaktifkan secara default coloropsi atau ketika GREP_COLORStelah ditetapkan.

Adam
sumber
1
Terima kasih untuk "... Anda harus menghubungi tim pengembang grep ...". Ini memberi saya umpan balik positif. Sekarang saya tahu bahwa saya bukan satu-satunya yang berpikir ada sesuatu yang hilang di sini.
guettli
Saya menambahkan komentar Anda "... Anda harus menghubungi tim pengembang grep ..." sebagai strateg6 untuk pertanyaan itu. Sampai sekarang ini adalah jawaban favorit saya.
guettli
0

Ini adalah solusi dari jawaban teratas oleh @NominalAnimal tetapi dengan yang biasa grep: ...dalam peringatan (bukan /bin/grep: ...):

#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"
Kirill Bulygin
sumber
Saya tahu cara menulis pembungkus. Wrapper bukan solusi dalam konteks ini.
guettli
@guettli Yah, jawabannya tidak dimaksudkan untuk mengatasi situasi Anda dengan tepat ... Jika komentar memiliki fitur format yang sama dengan jawaban, itu akan menjadi komentar. (Dan saya memiliki suntingan yang sama yang ditolak karena tidak dimaksudkan oleh penulis asli atau semacamnya.) Adapun situasi Anda, saya kira jawaban literal yang tepat untuk pertanyaan Anda adalah: "Strategi NICE-and-EASY" yang lain tidak ada.
Kirill Bulygin