Saya mencoba membuat daftar pengguna yang memiliki set direktori home yang tidak ada. Sepertinya saya harus dapat melakukan ini dengan awk, tetapi ada yang salah dengan sintaks saya.
Itu terus memberi tahu saya "Sintaks Tidak Valid" di]. Apa yang saya lakukan salah?
awk -F: '{ if(![ -d "$6"]){ print $1 " " $3 " " $7}}' /etc/passwd
Kode terakhir yang mungkin akan saya gunakan adalah:
awk -F: '{if(system( "[ -d " $6 " ]") == 1 && $7 != "/sbin/nologin" ) {print "The directory " $6 " does not exist for user " $1 }}' /etc/passwd
Dan saya punya pertanyaan terkait di sini .
/bin/ls
:echo ';ls;' | awk '{ print system("[ ! -d " $1 " ]") }'
Saya tidak berpikir itu
[ -d ]
adalahawk
sesuatu, itu masalah shell. Saya hanya akan melakukannya dengan cara ini sebagai gantinya:Tentu saja, sebagaimana ditunjukkan dengan sangat tepat oleh @Janis, Anda dapat melakukan semuanya di shell:
sumber
awk
sebenarnya tidak diperlukan; karena Anda tetap menggunakan shell, Anda juga bisa melakukannyawhile IFS=: read -r name x uid x x x shell rest ; do ... ; done </etc/passwd
.awk -F: '{print $6}' /etc/passwd | while read dir; do [ -d "$dir" ] || echo "no results for $dir"; done
.[ -d "$6"]
sebenarnya sintaks bash, bukan awk. The[
terlihat seperti sintaks normal, tapi (di salah satu bash / weirdnesses Linux lebih baik) itu sebenarnya sinonim untuktest
program executable (atau mungkin bash built-in versi itu, dan, hanya untuk menjadi aneh, bash memerlukan pencocokan]
yang doesn dapat melakukan apa pun yang saya ketahui selain untuk menyesatkan Anda untuk berpikir bahwa semuanya benar-benar sintaks dan bukan program). Bagaimanapun, itu bukan sesuatu yang diketahui oleh orang awk. Itu sebabnya Anda memerlukansystem()
fungsi untuk mengaksesnya dengan merujuknya dalam konteks bash di mana ia dipahamiAnda dapat menggunakan getline :
sumber
awk
, tetapi sayangnya tidak berfungsi untuk direktori.Jika Anda benar-benar menggunakan
gawk
(meskipun Anda mungkin menggunakannawk
, ataumawk
, dalam hal ini tidak akan berlaku), Anda dapat melakukan ini native menggunakan salah satu ekstensi loadable tersedia sejak v4.0. Saya menggunakangawk-4.1.x
(v4.0 memiliki variasi pada sintaks untuk memuat ekstensi).Memuat
filefuncs
ekstensi menambahkan (antara lain)stat()
fungsi:Lihat
filefuncs(3am)
halaman manual untuk detail tentang ekstensi ini.Jalankan dengan sesuatu seperti:
Anda dapat mengonfirmasi bahwa
gawk
biner Anda mendukung ekstensi dengan:Selain:
gawk
juga dilengkapi dengan fungsi perpustakaan kecil untuk membacapasswd
file, Anda dapat memanggilnya seperti:Saya lebih suka menggunakan
getent
sistem Linux / glibc karena mendukung nsswitch.sumber
gawk
penawaran v4 ini. Terima kasih!Ini hampir ...
sumber
Berikut ini solusinya
gawk
dan/bin/sh
Kode:
menjelaskan:
IFS="" read -r dir; [ -d "$dir" ]; echo $?
adalah kode shell yang membaca path dari stdin dan menghasilkan0
jika itu adalah direktori, yang lain1
print $6 |& cmd
pipa nama file ke perintah.|&
adalah ekstensi GNU-awk.cmd |& getline x
membaca output dari perintah ke dalam GNU-awkclose(cmd)
menyelesaikan perintah, sehingga baris selanjutnya dapat menjalankan satu lagiif (x)
mengeksekusiprint
hanya jikax
tidak0
(jadi direktori tidak ada)Saya tidak menyarankan untuk melakukannya dengan cara ini, karena sangat lambat dan kikuk. Tetapi resep ini aman , sehingga input tidak teratur tidak membahayakan. (Sepertinya tidak
/etc/passwd
berisi data berbahaya, tetapi mungkin seseorang ingin menggunakannya dengan data dari sumber yang tidak tepercaya).Jika Anda tidak dapat menggunakan
gawk
, ini sangat disayangkan. Dalam hal ini Anda tidak punya|&
. Normalawk
hanya dapat melakukan salah satu dari tiga berikut:print "data" | cmd; close(cmd)
: Pipa data menjadi perintahgetline data < cmd; close(cmd)
: Baca data dari sebuah perintahret = system(cmd)
: Dapatkan kode pengembalian perintah"Normal"
awk
tidak bisa menyalurkan data ke dalam skrip dan mendapatkan sesuatu dari itu pada saat yang sama (setidaknya saya tidak menemukan cara untuk itu), jadi Anda memerlukan beberapa file perantara (tempfile) yang bahkan lebih canggung.Pengamatan yang menarik adalah, bahwa tugas yang mudah dapat dilakukan dengan shell sendiri, juga:
Anda tidak perlu
bash
, setiap shell Bourne-normal dapat mengeksekusi kode di atas.Perhatikan bahwa kode shell di atas sedikit lebih rumit daripada yang benar-benar dibutuhkan, tetapi ini akan menjadi petunjuk tentang cara untuk benar-benar bekerja dengannya (untuk orang-orang yang tidak sepenuhnya berpengalaman dalam cara shell bekerja).
sumber