Đầu ra grep màu: Không phải GREP_OPTIONS không bí danh


10

Tôi muốn đầu ra màu của grep.

.... Nhưng

  • Chiến lược 1: GREP_OPTIONS. Nhưng điều này không được chấp nhận. Xem http://www.gnu.org/software/grep/manual/html_node/EnFE-Variabled.html
  • Stragegy 2: GREP_COLORS trông giống như một giải pháp ngay từ cái nhìn đầu tiên, nhưng điều này làm một cái gì đó khác biệt.
  • Chiến lược 3: bí danh. Điều này không hoạt động find ... | xargs grep, vì xargs không đánh giá bí danh.
  • Chiến lược 4: Viết một kịch bản bao bọc đơn giản. Không, tôi nghĩ rằng điều này là quá bẩn và gây ra nhiều rắc rối hơn nó giải quyết.
  • Chiến lược 5: vá mã nguồn
  • Chiến lược 6: Liên hệ với nhà phát triển grep, yêu cầu thay thế GREP_OPTIONS
  • Chiến lược NICE-and-EASY: ... điều này còn thiếu. Tôi không có đầu mối.

Làm thế nào để giải quyết điều này?

Cảm ơn bạn vi đa cô găng giup!

... nhưng tôi không thể đưa tiền thưởng

Gọi tôi là thô lỗ, kiêu ngạo, lăng mạ, lăng mạ ....

Tôi chỉ thấy xung quanh công việc - không có giải pháp. Không có câu trả lời thỏa mãn câu hỏi.

Cảm ơn vì nỗ lực của bạn.


1
Bạn đã từ chối hai đề xuất để sử dụng tập lệnh bao bọc (Chiến lược 4 của bạn) là "không thực sự là một câu trả lời". Bạn có thể mô tả những gì "bẩn", "rắc rối" hoặc "không thực sự là một câu trả lời" về nó? Có lẽ đó là một vấn đề riêng biệt có thể được giải quyết.
JigglyNaga

2
chiến lược 5 là vá mã nguồn và đặt color_optionthành2 ...
don_crissti

2
@JigglyNaga đây là lời giải thích của tôi tại sao một tập lệnh bao bọc không phải là một giải pháp. Nhóm chúng tôi quản lý một số máy chủ. Ít hơn ngàn tại thời điểm này, nhưng số lượng đang tăng lên. Có, chúng tôi sử dụng quản lý cấu hình và sẽ dễ dàng triển khai một tập lệnh cho tất cả chúng. Nhưng tôi muốn mọi thứ trở nên dễ dàng và đơn giản (nghĩ về các thành viên mới trong nhóm. Tôi không muốn nhầm lẫn họ). Các --colortùy chọn đã có giá trị auto. Tôi chỉ không biết tại sao bạn không thể kích hoạt nó theo mặc định.
guettli

Bạn nên sử dụng chiến lược 4 hoặc 5 - Tôi thích chiến lược 4 với tập lệnh dash / sh tối thiểu ( exec grep --color=auto "$@"), tùy ý có tên khác ( grepchoặc colorgrep). Điều này có chi phí không đáng kể (và không có quá trình đồng thời bổ sung trong thời gian chạy). Lý do bạn đã gắn nhãn cho chúng là "không đủ dễ dàng" là vì bạn không thấy tính năng này đủ hữu ích để dành nỗ lực một lần (tương đối ít) để thực hiện nó và đang tìm kiếm người khác làm điều đó cho bạn. Bởi vì điều này, các bình luận "không thực sự là một câu trả lời" cho các câu trả lời được đăng là khá thô lỗ.
Động vật danh nghĩa

1
@NominalAnimal Vâng, bạn nói đúng "không thực sự là một câu trả lời" nghe có vẻ thô lỗ. Tôi không phải là người bản ngữ. Từ ngữ nào (chuyển cùng một thông điệp) sẽ tốt hơn?
guettli

Câu trả lời:


13

Một số lý do OP đã tuyên bố các tùy chọn không phù hợp không có cơ sở trong thực tế. Ở đây, tôi chỉ ra loại hiệu ứng sử dụng chiến lược 4 của OP có:


Trên hầu hết các bản phân phối, grepđược cài đặt trong /bin(điển hình) hoặc /usr/bin(OpenSUSE, có thể là các bản phân phối khác) và mặc định PATHchứa /usr/local/bintrước /binhoặc /usr/bin. Điều này có nghĩa là nếu bạn tạo /usr/local/bin/grepbằng

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

nơi /bin/shcó vỏ tương thích POSIX do phân phối của bạn cung cấp, thường là bash hoặc dash. Nếu greplà trong /usr/bin, sau đó làm cho

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

Chi phí hoạt động của kịch bản này là tối thiểu. Câu execlệnh có nghĩa là trình thông dịch kịch bản được thay thế bằng greptệp nhị phân; điều này có nghĩa là shell không còn trong bộ nhớ trong khi grepđang được thực thi. Do đó, chi phí duy nhất là một lần thực hiện thêm của trình thông dịch kịch bản, tức là độ trễ nhỏ trong thời gian đồng hồ treo tường. Độ trễ gần như không đổi (chỉ thay đổi tùy thuộc vào việc có grepshđã có trong bộ đệm trang hay không và tùy thuộc vào mức độ băng thông I / O có sẵn) và không phụ thuộc vào thời gian grepthực thi hoặc lượng dữ liệu mà nó xử lý.

Vì vậy, độ trễ đó là bao lâu, tức là chi phí được thêm bởi tập lệnh bao bọc?

Để tìm hiểu, tạo tập lệnh trên và chạy

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

Trên máy của tôi, cái trước mất 0,005 giây thời gian thực (qua một số lượng lớn các lần chạy), trong khi cái sau mất 0,006 giây thời gian thực. Do đó, chi phí sử dụng trình bao bọc trên máy của tôi là 0,001s (hoặc ít hơn) cho mỗi lần gọi.

Điều này là không đáng kể.

Tôi cũng không thấy bất cứ điều gì "bẩn" về điều này, bởi vì nhiều ứng dụng và tiện ích phổ biến sử dụng cùng một cách tiếp cận. Để xem danh sách như vậy trên máy của bạn /bin/usr/binchỉ cần chạy

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

Trên máy tính của tôi, kết quả trên đã bao gồm egrep, fgrep, zgrep, which, 7z, chromium-browser, ldd, và xfig, mà tôi sử dụng khá thường xuyên. Trừ khi bạn coi toàn bộ phân phối của mình là "bẩn" vì dựa vào các tập lệnh của trình bao bọc, bạn không có lý do gì để xem các tập lệnh trình bao bọc đó là "bẩn".


Đối với các vấn đề như vậy, một kịch bản trình bao bọc có thể gây ra:

Nếu chỉ sử dụng con người (như trái ngược với các kịch bản) đang sử dụng các phiên bản của grep rằng giá trị mặc định để hỗ trợ màu nếu đầu ra là một thiết bị đầu cuối, sau đó kịch bản wrapper thể được đặt tên colorgrephoặc cgrephoặc bất cứ điều gì OP thấy phù hợp.

Điều này tránh tất cả các vấn đề tương thích có thể, bởi vì hành vi của grepkhông thay đổi chút nào.


Kích hoạt greptùy chọn với tập lệnh bao bọc, nhưng theo cách tránh mọi vấn đề mới:

Chúng tôi có thể dễ dàng viết lại tập lệnh trình bao bọc để hỗ trợ một tùy chỉnh GREP_OPTSngay cả khi GREP_OPTIONSkhông được hỗ trợ (vì nó đã bị phản đối). Bằng cách này, người dùng có thể chỉ cần thêm export "GREP_OPTIONS=--color=auto"hoặc tương tự với hồ sơ của họ. /usr/local/bin/grepsau đó

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

Lưu ý rằng không có dấu ngoặc kép xung quanh $GREP_OPTIONS, để người dùng có thể chỉ định nhiều hơn một tùy chọn.

Trên hệ thống của tôi, việc thực thi time /usr/local/bin/grep --versionvới GREP_OPTIONSrỗng, hoặc với GREP_OPTIONS=--color=auto, cũng nhanh như phiên bản trước của tập lệnh bao bọc; tức là, thường mất một mili giây để thực thi hơn đơn giản grep.

Phiên bản cuối cùng này là phiên bản mà cá nhân tôi khuyên bạn nên sử dụng.


Tóm lại, chiến lược 4 của OP:

  • được khuyến khích bởi các grepnhà phát triển

  • là tầm thường để thực hiện (hai dòng)

  • có chi phí không đáng kể (độ trễ thêm một phần nghìn giây cho mỗi lần gọi trên máy tính xách tay cụ thể này; dễ dàng xác minh trên mỗi máy)

  • có thể được triển khai như một tập lệnh bao bọc có thêm GREP_OPTShỗ trợ (để thay thế không dùng nữa / không được hỗ trợ GREP_OPTIONS)

  • có thể được triển khai (như colorgrep/ cgrep) hoàn toàn không ảnh hưởng đến tập lệnh hoặc người dùng hiện tại

Bởi vì nó là một kỹ thuật đã được sử dụng rộng rãi trong các bản phân phối Linux, nên đây là một kỹ thuật phổ biến và không "bẩn".

Nếu được triển khai như một trình bao bọc riêng ( colorgrep/ cgrep), nó không thể tạo ra vấn đề mới vì nó hoàn toàn không ảnh hưởng đến grephành vi. Nếu được triển khai như một tập lệnh bao bọc có thêm GREP_OPTShỗ trợ, việc sử dụng GREP_OPTS=--color=autocó chính xác các rủi ro tương tự (các vấn đề với các tập lệnh hiện tại) mà ngược dòng thêm mặc định --color=autosẽ. Do đó, nhận xét rằng điều này "tạo ra nhiều vấn đề hơn nó giải quyết" là hoàn toàn không chính xác: không có vấn đề bổ sung nào được tạo ra.


3

Tài liệu bạn cung cấp với chiến lược đầu tiên nói:

Vui lòng sử dụng một bí danh hoặc tập lệnh thay thế. Ví dụ: nếu grep nằm trong thư mục '/ usr / bin', bạn có thể thêm $ HOME / bin vào PATH của mình và tạo tập lệnh thực thi $ HOME / bin / grep chứa thông tin sau:

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

Vì vậy, nếu bí danh là không thể đối với bạn, kịch bản trình bao bọc là cách duy nhất.


Đó là Chiến lược 4 ... không thực sự là một câu trả lời.
guettli

3

Lý do GREP_OPTIONSbiến không được chấp nhận là vì nó có xu hướng gây ra sự cố khi grepđược gọi ở đâu đó trong tập lệnh và tập lệnh không hoạt động với các tùy chọn thay thế đến từ biến. Nếu bạn viết một tập lệnh bao bọc cho grepthì bạn có cùng một vấn đề, trừ khi bạn đặt cho nó một tên khác .

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

Ngoài ra, lưu trữ các tùy chọn yêu thích của bạn trong một biến. Trong các shell khác với zsh, điều này rất cồng kềnh nếu các tùy chọn chứa các ký tự đại diện ( \[*?), nhưng nếu không, bạn chỉ có thể sử dụng biến không được trích dẫn để nhận lệnh với các đối số.

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

Lưu ý rằng GNU và BSD grep có thể xử lý đệ quy cây thư mục, điều này làm giảm nhu cầu findkết hợp với grephầu hết thời gian.


1
Đó là Chiến lược 4 ... không thực sự là một câu trả lời.
guettli

@guettli, đó là câu trả lời đúng. Nếu bạn muốn một lệnh có hành vi khác grep, bạn cần một lệnh có tên khác hoặc nếu bạn giữ cùng tên, bạn sẽ phá vỡ các tập lệnh mong đợi hành vi gốc / chuẩn. Đó là sạch nhất và không gây thêm rắc rối .
Stéphane Chazelas

@ StéphaneChazelas vâng bạn đúng. Đây là câu trả lời đúng theo quan điểm của bạn.
guettli

1

Cách dễ nhất là sử dụng bí danh (chiến lược 3). Nếu bạn thực sự quan tâm đến xargslệnh, bạn vẫn có thể ghi đè nó bằng hàm 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
}

Nhưng điều này không tốt hơn việc sử dụng lệnh bao bọc dường như là giải pháp được đề xuất bởi grepnhóm:

/usr/local/bin/grep:

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

Theo ý kiến ​​khiêm tốn của tôi, bạn nên liên hệ với nhóm grepnhà phát triển để yêu cầu họ cung cấp một sự thay thế đơn giản cho GREP_OPTIONSbiến sẽ cho phép màu greptheo một số biến môi trường.

Nó sẽ khá đơn giản để họ bật theo mặc định colortùy chọn hoặc khi GREP_COLORSđã được đặt.


1
Cảm ơn bạn vì "... bạn nên liên hệ với nhóm nhà phát triển grep ...". Điều này mang lại cho tôi thông tin phản hồi tích cực. Bây giờ tôi biết rằng tôi không phải là người duy nhất nghĩ rằng thiếu một cái gì đó ở đây.
guettli

Tôi đã thêm nhận xét của bạn "... bạn nên liên hệ với nhóm nhà phát triển grep ..." dưới dạng chiến lược6 cho câu hỏi. Cho đến bây giờ đây là câu trả lời yêu thích của tôi.
guettli

0

Đây là giải pháp từ câu trả lời hàng đầu của @NominalAnimal nhưng với thông thường grep: ...trong các cảnh báo (thay vì /bin/grep: ...):

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

Tôi biết làm thế nào để viết giấy gói. Một trình bao bọc không phải là một giải pháp trong bối cảnh này.
guettli

@guettli Chà, câu trả lời không nhằm giải quyết chính xác tình huống của bạn ... Nếu bình luận có các tính năng định dạng giống như câu trả lời, đó sẽ là một bình luận. .
Kirill Bulygin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.