Saya telah mencari jawaban untuk ini secara online tetapi belum dapat menemukan jawaban apa pun di sekitar ini (mencari bash dan color menghasilkan hasil untuk banyak hal terkait warna lainnya).

Yang ingin saya lakukan adalah mengimplementasikan argumen --color=(never|always|auto) dalam skrip bash saya sendiri yang serupa dengan opsi di ls, grep atau perintah lainnya. Saya tidak pernah mengerti bagaimana opsi auto bekerja di bawah selimut untuk mengetahui apakah output dari suatu perintah sedang disalurkan atau dialihkan.

Saya sedang memikirkan contoh sesuatu seperti ini:

example.sh
#!/bin/bash

text="This is some text"

if [[ "$1" == "--color=always" ]]; then
  echo -e "\e[1;36m${text}\e[0m" # light blue
elif [[  "$1" == "--color=never" ]]; then
  echo "$text"
elif [[  "$1" == "--color=auto" ]]; then
  if [ Being Redirect or Piped ]; then
    echo "$text"
  else
    echo -e "\e[1;36m${text}\e[0m" # light blue
  fi
fi

Saya telah melakukan beberapa pengujian, jika saya menentukan kode warna dalam string yang saya gema maka ketika disalurkan/dialihkan kode warna juga akan disalurkan/dialihkan (perilaku yang kami harapkan dengan --color=always). Selain itu jika saya tidak menempatkan kode warna dalam teks yang digaungkan, ini adalah perilaku yang saya harapkan dari --color=never (jelas). Apa yang saya tidak tahu adalah bagaimana mendapatkan sesuatu seperti --color=auto untuk bekerja yang menyadari pipa dan pengalihan; sesuatu yang berfungsi seperti berikut:

./example.sh --color=auto
=> This is some text # Entire string is colored light blue
./example.sh --color=auto | grep "text"
=> This is some text  # Piped text isn't colored so only "text" ends up colored  from the grep command (if grep is set to color it)

Saya tidak yakin bagaimana menerapkan ini (atau bahkan mungkin) dan googling sejauh ini tidak membantu. Saya tidak yakin apakah ini membantu atau relevan tetapi saya adalah pengguna linux (Ubuntu) dan menggunakan terminal dengan xterm-256color, saya tidak khawatir tentang portabilitas sekarang tetapi akan penasaran untuk solusi apa pun jika ada batasan pada jenis terminal yang akan digunakannya. Bimbingan apa pun tentang ini akan sangat dihargai.

2
blitz1616 22 Mei 2021, 06:37

2 jawaban

Jawaban Terbaik

Warna hanya bermakna ketika data dikeluarkan ke terminal sehingga opsi seperti --color=auto hanya perlu memeriksa apakah itu dicetak ke tty/pty. Untuk Bash Anda dapat menulis seperti ini:

color=... # auto | always | never
...
if [[ $color == auto ]]; then
  # 0 for stdin, 1 for stdout, 2 for stderr
  if [[ -t 1 ]]; then
    # we're writing to a tty so use colors
    ...
  else
    # not a tty, no colors
    ...
  fi
fi

Bahasa lain biasanya memiliki fungsi seperti isatty(3) untuk memeriksa apakah file yang terbuka adalah tty atau tidak.

4
pynexj 24 Mei 2021, 06:16

Gunakan fungsi. Gunakan variabel. Struktur kode dengan benar. Kode Anda dapat terlihat seperti berikut:

# parse arguments
color=... # auto | always | never

color_green() {
     if ((!use_color)); then return; fi
     echo "Output green color code"
}
color_reset() {
     if ((!use_color)); then return; fi
     echo "Output reset color code"
}
printf_green() {
    color_green
    printf "$@"
    color_reset
    printf "\n"
}

use_color=0
# enable coloring when always, or when output is a tty and auto
if [[ "$color" == always || ( "$color" == auto && -t 1 ) ]]; then
  use_color=1
fi

printf_green "Hello world"

jika ada batasan pada jenis terminal yang akan berfungsi.

Sakelar -t adalah standar dan harus tersedia di mana saja . Ini memanggil isatty() secara internal. Pengujian adalah fd 1 adalah terminal, pada dasarnya Anda menguji apakah keluaran terlihat oleh pengguna atau jika ia pergi ke program lain (mis. pipa) sebagai gantinya.

1
KamilCuk 24 Mei 2021, 07:30