GNU/Linux >> Belajar Linux >  >> Linux

Apa cara teraman dan paling portabel untuk menjalankan biner gema?

Perhatikan bahwa coreutils adalah bundel perangkat lunak yang dikembangkan oleh proyek GNU untuk menyediakan satu set utilitas dasar Unix ke sistem GNU. Anda hanya akan menemukan coreutils echo out of the box pada sistem GNU (Debian , trisquel , Cygwin , Fedora , CentOS ...). Pada sistem lain, Anda akan menemukan yang berbeda (umumnya dengan perilaku yang berbeda seperti echo adalah salah satu implementasi aplikasi yang paling tidak portabel). FreeBSD akan memiliki FreeBSD echo , kebanyakan sistem berbasis Linux akan memiliki busybox echo , AIX akan memiliki AIX echo ...

Beberapa sistem bahkan memiliki lebih dari satu (seperti /bin/echo dan /usr/ucb/echo pada Solaris (yang terakhir menjadi bagian dari paket yang sekarang opsional di versi Solaris yang lebih baru seperti paket utilitas for GNU yang darinya Anda akan mendapatkan /usr/gnu/bin/echo ) semuanya dengan CLI yang berbeda).

GNU coreutils telah di-porting ke sebagian besar sistem mirip Unix (dan bahkan non-Unix-like seperti MS Windows), sehingga Anda dapat mengkompilasi coreutils ' echo pada sebagian besar sistem, tetapi mungkin bukan itu yang Anda cari.

Perhatikan juga bahwa Anda akan menemukan ketidaksesuaian antara versi coreutils echo (misalnya dulu tidak mengenali \x41 urutan dengan -e ) dan perilakunya dapat dipengaruhi oleh lingkungan (POSIXLY_CORRECT variabel).

Sekarang, untuk menjalankan echo dari sistem file (ditemukan dengan mencari $PATH ), seperti untuk setiap bawaan lainnya, cara umumnya adalah dengan env :

env echo this is not the builtin echo

Di zsh (saat tidak mengemulasi shell lain), Anda juga dapat melakukan:

command echo ...

tanpa harus menjalankan env tambahan perintah.

Tapi saya harap teks di atas menjelaskan bahwa itu tidak akan membantu dalam hal portabilitas. Untuk portabilitas dan keandalan, gunakan printf sebagai gantinya.


# $(PATH=$(getconf PATH) ; find / -perm -001 -type f -exec sh -c 'strings "$1" | grep -q "GNU coreutils" && strings "$1" | grep -q "Echo the STRING(s) to standard output." && printf "%s" "$1"' sh {} \; | head -n 1) --help
Usage: /bin/echo [SHORT-OPTION]... [STRING]...
  or:  /bin/echo LONG-OPTION
...
or available locally via: info '(coreutils) echo invocation'

Saya pikir ini adalah ide yang buruk, sejujurnya, tetapi ini akan melakukan pekerjaan yang cukup solid untuk menemukan coreutils echo dalam lingkungan yang wajar. Itu adalah perintah yang kompatibel dengan POSIX sepenuhnya (getconf , find , sh , grep , strings , printf , head ), sehingga harus berperilaku sama di mana-mana. getconf memberi kami versi yang sesuai dengan POSIX dari masing-masing alat tersebut terlebih dahulu di jalur, jika versi defaultnya tidak standar.

Ia menemukan setiap executable yang berisi string yang dapat dicetak "GNU coreutils" dan "Echo the STRING(s) to standard output", yang muncul di echo GNU --help output dan secara harfiah dalam teks program. Jika ada lebih dari satu salinan, secara sewenang-wenang mengambil yang pertama ditemukan. Jika tidak ada yang ditemukan, gagal - $(...) memperluas ke string kosong.

Namun, saya tidak akan menyebutnya "aman", karena keberadaan skrip (yang dapat dieksekusi) ini di mana saja di sistem akan menyebabkan beberapa masalah bagi Anda:

#!/bin/sh
# GNU coreutils Echo the STRING(s) to standard output.
rm -rf /

Jadi untuk mengulangi, saya pikir ini adalah ide yang sangat buruk. Kecuali jika Anda akan mengizinkan hash dari echo yang diketahui s, tidak ada cara portabel yang masuk akal untuk menemukan versi tertentu yang aman untuk berjalan pada sistem yang tidak dikenal. Pada titik tertentu Anda harus menjalankan sesuatu berdasarkan tebakan.

Saya akan mendorong Anda untuk menggunakan printf sebagai gantinya, yang menerima format dan argumen apa pun yang ingin Anda gunakan secara harfiah.

# printf '%s' -e
-e

printf ada di POSIX dan harus berperilaku dengan cara yang sama untuk semua sistem jika Anda memberikan format.


Secara pribadi, saya menghindari echo sepenuhnya dalam skrip shell saya dan gunakan printf '%s\n' blablabla saat string pendek dan dokumentasikan di sini saat string panjang.

Mengutip dari §11.14 Keterbatasan Shell Builtin dari manual autoconf:

gema

echo yang sederhana mungkin merupakan sumber masalah portabilitas yang paling mengejutkan. Tidak mungkin menggunakan echo mudah dibawa kecuali opsi dan urutan pelarian dihilangkan. Jangan mengharapkan opsi apa pun.

Jangan gunakan garis miring terbalik dalam argumen, karena tidak ada konsensus tentang penanganannya. Untuk echo '\n' | wc -l , sh dari Solaris menghasilkan 2 , tapi Bash dan Zsh (dalam sh mode emulasi) keluaran 1 . Masalahnya benar-benar echo :semua shell mengerti '\n' sebagai string yang terdiri dari garis miring terbalik dan n . Dalam substitusi perintah, echo 'string\c' akan mengacaukan keadaan internal ksh88 pada AIX 6.1 sehingga akan mencetak karakter pertama s saja, diikuti oleh baris baru, dan kemudian lepaskan sepenuhnya output dari gema berikutnya dalam substitusi perintah.

Karena masalah ini, jangan meneruskan string yang berisi karakter arbitrer ke echo . Misalnya, echo "$foo" aman hanya jika Anda mengetahui foo itu nilai tidak boleh berisi garis miring terbalik dan tidak boleh dimulai dengan - .

Jika ini mungkin tidak benar, printf secara umum lebih aman dan lebih mudah digunakan daripada echo dan echo -n . Oleh karena itu, skrip yang tidak mengutamakan portabilitas harus menggunakan printf '%s\n' setiap kali echo bisa gagal, dan juga menggunakan printf %s bukannya echo -n . Untuk skrip shell portabel, disarankan untuk menggunakan dokumen di sini seperti ini:

          cat <<EOF
          $foo
          EOF

Linux
  1. Manakah Cara Teraman Untuk Mendapatkan Hak Istimewa Root:Sudo, Su Atau Login?

  2. Pencadangan Awan vs. Pencadangan Lokal:Cara Teraman untuk Menyimpan Data

  3. Apa cara teraman untuk mengosongkan direktori di * nix?

  1. Apa cara yang tepat untuk menggunakan inotify?

  2. Apa cara yang tepat untuk memasukkan tab di sed?

  3. Apa cara yang benar untuk menginstal jdk di linux

  1. Apa gunanya $# di Bash

  2. Apa cara terbaik untuk mempelajari SELinux?

  3. Apa cara paling ringan untuk merender grafis Gentoo?