Temukan file yang dapat ditulis pengguna, efisien dengan pembuatan proses minimal

20

Saya adalah root. Saya ingin tahu apakah pengguna non-root memiliki akses tulis ke beberapa file - ribuan di antaranya. Bagaimana melakukannya secara efisien sambil menghindari proses pembuatan?

Howard
sumber
Tolong tunjukkan kepada kami apa yang sebenarnya Anda lakukan!
F. Hauri
Jenis pertanyaan yang sama dengan unix.stackexchange.com/a/88591
Stéphane Chazelas
Dengan asumsi Anda tidak peduli dengan kondisi balapan, mengapa tidak menelepon access(2)dengan UID nyata yang diatur dengan tepat (mis. Via setresuid(2)atau setara portabel)? Maksudku, aku akan kesulitan melakukan itu dari bash, tapi aku yakin Perl / Python bisa mengatasinya.
Kevin
1
@ Kevin, shell [ -wbiasanya menggunakan akses (2) atau setara. Anda juga perlu mengatur gids di samping uid (seperti su atau sudo do). bash tidak memiliki dukungan bawaan untuk itu tetapi zsh melakukannya.
Stéphane Chazelas
@ StéphaneChazelas - Anda dapat menggunakan chgrpshell apa pun.
mikeserv

Jawaban:

2

Mungkin seperti ini:

#! /bin/bash

writable()
{
    local uid="$1"
    local gids="$2"
    local ids
    local perms

    ids=($( stat -L -c '%u %g %a' -- "$3" ))
    perms="0${ids[2]}"

    if [[ ${ids[0]} -eq $uid ]]; then
        return $(( ( perms & 0200 ) == 0 ))
    elif [[ $gids =~ (^|[[:space:]])"${ids[1]}"($|[[:space:]]) ]]; then
        return $(( ( perms & 020 ) == 0 ))
    else
        return $(( ( perms & 2 ) == 0 ))
    fi
}

user=foo
uid="$( id -u "$user" )"
gids="$( id -G "$user" )"

while IFS= read -r f; do
    writable "$uid" "$gids" "$f" && printf '%s writable\n' "$f"
done

Di atas menjalankan program eksternal tunggal untuk setiap file, yaitu stat(1).

Catatan: Ini mengasumsikan bash(1), dan inkarnasi Linux dari stat(1).

Catatan 2: Silakan baca komentar dari Stéphane Chazelas di bawah ini untuk masa lalu, sekarang, masa depan, dan potensi bahaya dan keterbatasan dari pendekatan ini.

lcd047
sumber
Itu bisa mengatakan file dapat ditulisi meskipun pengguna tidak memiliki akses ke direktori di mana itu.
Stéphane Chazelas
Itu mengasumsikan nama file tidak mengandung karakter baris baru dan jalur file yang dilewati stdin tidak dimulai dengan -. Anda dapat memodifikasinya untuk menerima daftar yang dibatasi NUL sebagai gantinya denganread -d ''
Stéphane Chazelas
Perhatikan bahwa tidak ada yang namanya stat Linux . Linux adalah kernel yang ditemukan di beberapa sistem GNU dan non-GNU. Meskipun ada perintah (seperti dari util-linux) yang secara khusus ditulis untuk Linux, yang statAnda maksud bukan, itu adalah perintah GNU yang telah porting ke sebagian besar sistem, tidak hanya Linux. Perhatikan juga bahwa Anda memiliki statperintah di Linux jauh sebelum GNU statditulis ( statzsh builtin).
Stéphane Chazelas
2
@ Stéphane Chazelas: Perhatikan bahwa tidak ada yang namanya stat Linux. - Saya yakin saya menulis "inkarnasi Linux stat(1)". Saya mengacu pada stat(1)yang menerima -c <format>sintaks, yang bertentangan dengan, katakanlah, sintaks BSD -f <format>. Saya juga percaya itu cukup jelas saya tidak merujuk stat(2). Saya yakin halaman wiki tentang sejarah perintah umum akan sangat menarik.
lcd047
1
@ Stéphane Chazelas: Bisa dikatakan sebuah file dapat ditulisi meskipun pengguna tidak memiliki akses ke direktori di mana ia berada. - Benar, dan mungkin batasan yang masuk akal. Itu mengasumsikan nama file tidak mengandung karakter baris baru - Benar, dan mungkin batasan yang masuk akal. dan path file yang diteruskan pada stdin jangan mulai dengan - - Diedit, terima kasih.
lcd047
17

TL; DR

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -l -0ne 'print if -w'

Anda perlu menanyakan sistem apakah pengguna memiliki izin menulis. Satu-satunya cara yang dapat diandalkan adalah untuk mengganti gid yang efektif, gid dan suplementasi yang efektif menjadi milik pengguna dan menggunakannyaaccess(W_OK) panggilan sistem (bahkan yang memiliki beberapa keterbatasan pada beberapa sistem / konfigurasi).

Dan ingatlah bahwa tidak memiliki izin menulis ke file tidak selalu menjamin bahwa Anda tidak dapat mengubah konten file di jalur itu.

Cerita yang lebih panjang

Mari kita pertimbangkan apa yang diperlukan misalnya bagi $ user untuk memiliki akses tulis /foo/file.txt(dengan asumsi tidak ada /foodan /foo/file.txtmerupakan symlink)?

Dia membutuhkan:

  1. cari akses ke /(tidak perlu read)
  2. cari akses ke /foo(tidak perlu read)
  3. akses tulis ke/foo/file.txt

Anda sudah dapat melihat bahwa pendekatan (seperti @ lcd047 atau @ apaul ) yang memeriksa hanya izin file.txttidak akan berfungsi karena mereka bisa mengatakan file.txtitu dapat ditulisi bahkan jika pengguna tidak memiliki izin pencarian untuk /atau/foo .

Dan pendekatan seperti:

sudo -u "$user" find / -writeble

Tidak akan berfungsi karena itu tidak akan melaporkan file dalam direktori pengguna tidak memiliki akses baca ( findberjalan karena $usertidak dapat membuat daftar konten mereka) bahkan jika ia dapat menulis kepada mereka.

Jika kita melupakan ACL, sistem file read-only, flag FS (seperti immutable), langkah-langkah keamanan lainnya (apparmor, SELinux, yang bahkan dapat membedakan antara berbagai jenis penulisan) dan hanya fokus pada izin tradisional dan atribut kepemilikan, untuk mendapatkan diberikan (cari atau tulis) izin, itu sudah cukup rumit dan sulit untuk diungkapkan find .

Anda membutuhkan:

  • jika file tersebut milik Anda, Anda memerlukan izin untuk pemiliknya (atau memiliki 0)
  • jika file tersebut bukan milik Anda, tetapi grup tersebut adalah salah satu milik Anda, maka Anda memerlukan izin untuk grup tersebut (atau minta 0).
  • jika tidak dimiliki oleh Anda, dan tidak di salah satu grup Anda, maka izin lainnya berlaku (kecuali uid Anda adalah 0).

Dalam findsintaksis, di sini sebagai contoh dengan pengguna uid 1 dan gids 1 dan 2, yaitu:

find / -type d \
  \( \
    -user 1 \( -perm -u=x -o -prune \) -o \
    \( -group 1 -o -group 2 \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) -o -type l -o \
    -user 1 \( ! -perm -u=w -o -print \) -o \
    \( -group 1 -o -group 2 \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

Yang itu memangkas direktori yang pengguna tidak memiliki hak untuk mencari dan untuk jenis file lainnya (symlink dikecualikan karena tidak relevan), memeriksa akses tulis.

Jika Anda juga ingin mempertimbangkan akses tulis ke direktori:

find / -type d \
  \( \
    -user 1 \( -perm -u=x -o -prune \) -o \
    \( -group 1 -o -group 2 \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user 1 \( ! -perm -u=w -o -print \) -o \
    \( -group 1 -o -group 2 \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

Atau untuk arbitrer $userdan keanggotaan grupnya diambil dari basis data pengguna:

groups=$(id -G "$user" | sed 's/ / -o -group /g'); IFS=" "
find / -type d \
  \( \
    -user "$user" \( -perm -u=x -o -prune \) -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" \( ! -perm -u=w -o -print \) -o \
    \( -group $groups \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

(total 3 proses:: id, seddan find)

Yang terbaik di sini adalah untuk turun pohon sebagai root dan memeriksa izin sebagai pengguna untuk setiap file.

 find / ! -type l -exec sudo -u "$user" sh -c '
   for file do
     [ -w "$file" ] && printf "%s\n" "$file"
   done' sh {} +

(Itu satu findproses ditambah satu sudodan shproses setiap beberapa ribu file, [dan printfbiasanya dibangun di shell).

Atau dengan perl:

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -l -0ne 'print if -w'

(3 proses secara total: find, sudodan perl).

Atau dengan zsh:

files=(/**/*(D^@))
USERNAME=$user
for f ($files) {
  [ -w $f ] && print -r -- $f
}

(0 total proses, tetapi menyimpan seluruh daftar file dalam memori)

Solusi tersebut bergantung pada access(2)panggilan sistem. Itu alih-alih mereproduksi algoritma yang digunakan sistem untuk memeriksa izin akses, kami meminta sistem untuk melakukan pemeriksaan dengan algoritma yang sama (yang memperhitungkan izin akun, ACL, bendera yang tidak dapat diubah, sistem file read-only ... ) itu akan digunakan jika Anda mencoba untuk membuka file untuk menulis, jadi terdekat Anda akan mendapatkan solusi yang dapat diandalkan.

Untuk menguji solusi yang diberikan di sini, dengan berbagai kombinasi pengguna, grup, dan izin, Anda dapat melakukan:

perl -e '
  for $u (1,2) {
    for $g (1,2,3) {
      $d1="u${u}g$g"; mkdir$d1;
      for $m (0..511) {
        $d2=$d1.sprintf"/%03o",$m; mkdir $d2; chown $u, $g, $d2; chmod $m,$d2;
        for $uu (1,2) {
          for $gg (1,2,3) {
            $d3="$d2/u${uu}g$gg"; mkdir $d3;
            for $mm (0..511) {
              $f=$d3.sprintf"/%03o",$mm;
              open F, ">","$f"; close F;
              chown $uu, $gg, $f; chmod $mm, $f
            }
          }
        }
      }
    }
  }'

Memvariasikan pengguna antara 1 dan 2 dan grup antara 1, 2, dan 3 dan membatasi diri hingga 9 bit yang lebih rendah dari izin karena sudah 9458694 file dibuat. Itu untuk direktori dan sekali lagi untuk file.

Itu menciptakan semua kemungkinan kombinasi u<x>g<y>/<mode1>/u<z>g<w>/<mode2>. Pengguna dengan uid 1 dan gids 1 dan 2 akan memiliki akses tulis, u2g1/010/u2g3/777tetapi tidak u1g2/677/u1g1/777misalnya.

Sekarang, semua solusi itu mencoba mengidentifikasi jalur file yang dapat dibuka oleh pengguna untuk ditulis, itu berbeda dari jalur di mana pengguna mungkin dapat mengubah konten. Untuk menjawab pertanyaan yang lebih umum itu, ada beberapa hal yang harus diperhatikan:

  1. $ user mungkin tidak memiliki akses tulis ke /a/b/filetetapi jika ia memiliki file(dan memiliki akses pencarian /a/b, dan sistem file tidak hanya-baca, dan file tidak memiliki bendera yang tidak dapat diubah, dan ia memiliki akses shell ke sistem), maka dia akan dapat mengubah izin filedan memberikan dirinya akses.
  2. Hal yang sama jika dia miliki /a/b tetapi tidak memiliki akses pencarian untuk itu.
  3. $ user mungkin tidak memiliki akses ke /a/b/filekarena ia tidak memiliki akses pencarian ke /aatau /a/b, tetapi file itu mungkin memiliki hard link /b/c/file, misalnya, dalam hal ini ia mungkin dapat memodifikasi konten /a/b/filedengan membukanya melalui /b/c/filejalurnya.
  4. Hal yang sama dengan bind-mounts . Dia mungkin tidak memiliki akses pencarian /a, tetapi /a/bdapat di -mount- in /c, sehingga dia dapat membuka fileuntuk menulis melalui /c/filejalur lainnya.
  5. Dia mungkin tidak memiliki izin menulis untuk /a/b/file, tetapi jika dia memiliki akses tulis untuk /a/bdia dapat menghapus atau mengganti nama filedi sana dan menggantinya dengan versinya sendiri. Dia akan mengubah konten file /a/b/filebahkan jika itu akan menjadi file yang berbeda.
  6. Hal yang sama jika dia punya akses tulis /a(dia bisa mengganti nama /a/bmenjadi /a/c, membuat /a/bdirektori baru dan baru filedi dalamnya.

Untuk menemukan jalur yang $userakan dapat dimodifikasi. Untuk mengatasi 1 atau 2, kita tidak bisa lagi mengandalkan access(2)panggilan sistem. Kami dapat menyesuaikan find -permpendekatan kami untuk menganggap akses pencarian ke direktori, atau menulis akses ke file segera setelah Anda pemiliknya:

groups=$(id -G "$user" | sed 's/ / -o -group /g'); IFS=" "
find / -type d \
  \( \
    -user "$user" -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" -print -o \
    \( -group $groups \) \( ! -perm -g=w -o -print \) -o \
    ! -perm -o=w -o -print

Kita dapat mengatasi 3 dan 4, dengan merekam perangkat dan nomor inode atau semua file $ user memiliki izin menulis dan melaporkan semua path file yang memiliki nomor dev + inode tersebut. Kali ini, kita bisa menggunakan yang lebih andal access(2) pendekatan berbasis :

Sesuatu seperti:

find / ! -type l -print0 |
  sudo -u "$user" perl -Mfiletest=access -0lne 'print 0+-w,$_' |
  perl -l -0ne '
    ($w,$p) = /(.)(.*)/;
    ($dev,$ino) = stat$p or next;
    $writable{"$dev,$ino"} = 1 if $w;
    push @{$p{"$dev,$ino"}}, $p;
    END {
      for $i (keys %writable) {
        for $p (@{$p{$i}}) {
          print $p;
        }
      }
    }'

5 dan 6 pada pandangan pertama diperumit dengan tsedikit izin. Ketika diterapkan pada direktori, itu adalah bit penghapusan terbatas yang mencegah pengguna (selain pemilik direktori) menghapus atau mengganti nama file yang tidak mereka miliki (walaupun mereka memiliki akses tulis ke direktori).

Misalnya, jika kita kembali ke contoh kita sebelumnya, jika Anda memiliki akses tulis ke /a, maka Anda harus dapat mengubah nama /a/buntuk /a/c, dan kemudian menciptakan sebuah /a/bdirektori dan baru filedi sana. Tetapi jika tbit sudah diaktifkan /adan Anda tidak memiliki /a, maka Anda hanya dapat melakukannya jika Anda memilikinya /a/b. Itu memberi:

  • Jika Anda memiliki direktori, sesuai 1, Anda dapat memberikan diri Anda akses tulis, dan bit itu tidak berlaku (dan Anda bisa menghapusnya), sehingga Anda dapat menghapus / mengganti nama / membuat ulang file atau direktori apa pun di sana, jadi semua jalur file di bawah ini milik Anda untuk ditulis ulang dengan konten apa pun.
  • Jika Anda tidak memilikinya tetapi memiliki akses tulis, maka:
    • Entah itu t bit tidak disetel, dan Anda berada dalam kasus yang sama seperti di atas (semua jalur file adalah milik Anda).
    • atau sudah diatur dan kemudian Anda tidak dapat memodifikasi file yang tidak Anda miliki atau tidak memiliki akses tulis, jadi untuk tujuan kami menemukan jalur file yang dapat Anda modifikasi, itu sama dengan tidak memiliki izin menulis sama sekali.

Jadi kita dapat mengatasi semua 1, 2, 5 dan 6 dengan:

find / -type d \
  \( \
    -user "$user" -prune -exec find {} + -o \
    \( -group $groups \) \( -perm -g=x -o -prune \) -o \
    -perm -o=x -o -prune \
  \) ! -type d -o -type l -o \
    -user "$user" \( -type d -o -print \) -o \
    \( -group $groups \) \( ! -perm -g=w -o \
       -type d ! -perm -1000 -exec find {} + -o -print \) -o \
    ! -perm -o=w -o \
    -type d ! -perm -1000 -exec find {} + -o \
    -print

Itu dan solusi untuk 3 dan 4 adalah independen, Anda dapat menggabungkan output mereka untuk mendapatkan daftar lengkap:

{
  find / ! -type l -print0 |
    sudo -u "$user" perl -Mfiletest=access -0lne 'print 0+-w,$_' |
    perl -0lne '
      ($w,$p) = /(.)(.*)/;
      ($dev,$ino) = stat$p or next;
      $writable{"$dev,$ino"} = 1 if $w;
      push @{$p{"$dev,$ino"}}, $p;
      END {
        for $i (keys %writable) {
          for $p (@{$p{$i}}) {
            print $p;
          }
        }
      }'
  find / -type d \
    \( \
      -user "$user" -prune -exec sh -c 'exec find "$@" -print0' sh {} + -o \
      \( -group $groups \) \( -perm -g=x -o -prune \) -o \
      -perm -o=x -o -prune \
    \) ! -type d -o -type l -o \
      -user "$user" \( -type d -o -print0 \) -o \
      \( -group $groups \) \( ! -perm -g=w -o \
         -type d ! -perm -1000 -exec sh -c 'exec find "$@" -print0' sh {} + -o -print0 \) -o \
      ! -perm -o=w -o \
      -type d ! -perm -1000 -exec sh -c 'exec find "$@" -print0' sh {} + -o \
      -print0
} | perl -l -0ne 'print unless $seen{$_}++'

Sebagaimana harus jelas jika Anda telah membaca semuanya sejauh ini, sebagian darinya setidaknya hanya berkaitan dengan izin dan kepemilikan, bukan fitur lain yang dapat memberikan atau membatasi akses tulis (hanya baca FS, ACL, bendera tidak berubah, fitur keamanan lainnya ...). Dan ketika kami memprosesnya dalam beberapa tahap, beberapa informasi itu mungkin salah jika file / direktori sedang dibuat / dihapus / diubah namanya atau izin / kepemilikannya dimodifikasi ketika skrip sedang berjalan, seperti pada server file yang sibuk dengan jutaan file .

Catatan portabilitas

Semua kode itu standar (POSIX, Unix for tbit) kecuali:

  • -print0adalah ekstensi GNU sekarang juga didukung oleh beberapa implementasi lainnya. Dengan findimplementasi yang tidak memiliki dukungan untuk itu, Anda dapat menggunakan -exec printf '%s\0' {} +sebagai gantinya, dan mengganti -exec sh -c 'exec find "$@" -print0' sh {} +dengan -exec sh -c 'exec find "$@" -exec printf "%s\0" {\} +' sh {} +.
  • perlbukan perintah yang ditentukan POSIX tetapi tersedia secara luas. Anda perlu perl-5.6.0atau di atas -Mfiletest=access.
  • zshbukan perintah yang ditentukan POSIX. Itu zshkode di atas harus bekerja dengan zsh-3 (1995) dan di atas.
  • sudobukan perintah yang ditentukan POSIX. Kode harus bekerja dengan versi apa pun selama konfigurasi sistem memungkinkan berjalan perlsebagai pengguna yang diberikan.
Stéphane Chazelas
sumber
Apa itu akses pencarian ? Saya belum pernah mendengarnya dalam izin tradisional: baca, tulis, eksekusi.
bela83
2
@ bela83, jalankan izin pada direktori (Anda tidak menjalankan direktori) diterjemahkan ke pencarian . Itulah kemampuan mengakses file di dalamnya. Anda dapat membuat daftar konten direktori jika Anda memiliki izin baca, tetapi Anda tidak dapat melakukan apa pun dengan file di dalamnya kecuali Anda juga memiliki xizin pencarian ( bit) pada direktori. Anda juga dapat memiliki izin pencarian tetapi tidak membaca , artinya file di sana disembunyikan untuk Anda, tetapi jika Anda tahu namanya, Anda dapat mengaksesnya. Contoh tipikal adalah direktori file sesi php (sesuatu seperti / var / lib / php).
Stéphane Chazelas
2

Anda dapat menggabungkan opsi dengan findperintah, sehingga akan menemukan file dengan mode dan pemilik yang ditentukan. Contohnya:

$ find / \( -group staff -o -group users \) -and -perm -g+w

Perintah di atas akan mencantumkan semua entri yang termasuk dalam grup "staf" atau "pengguna" dan memiliki izin menulis untuk grup itu.

Anda juga harus memeriksa entri yang dimiliki oleh pengguna Anda, dan file yang dapat ditulisi dunia, jadi:

$ find / \( -user yourusername -or \
             \(  \( -group staff -o -group users \) -and -perm -g+w \
             \) -or \
            -perm -o+w \
         \)

Namun, perintah ini tidak akan cocok dengan entri dengan ACL yang diperluas. Jadi, Anda dapat sumenemukan semua entri yang dapat ditulis:

# su - yourusername
$ find / -writable
apaul
sumber
Itu akan mengatakan bahwa file dengan r-xrwxrwx yourusername:anygroupatau r-xr-xrwx anyone:staffdapat ditulisi.
Stéphane Chazelas
Itu juga akan dilaporkan sebagai file yang dapat ditulisi yang ada di direktori yourusernametidak memiliki akses.
Stéphane Chazelas
1

Pendekatannya tergantung pada apa yang sebenarnya Anda uji.

  1. Apakah Anda ingin memastikan akses tulis dimungkinkan?
  2. Apakah Anda ingin memastikan kurangnya akses tulis?

Ini karena ada begitu banyak cara untuk sampai pada angka 2) dan jawaban Stéphane mencakup semua ini dengan baik (tidak dapat diubah adalah untuk mengingat), dan ingat bahwa ada cara fisik juga, seperti melepas drive atau membuatnya hanya-baca di sebuah tingkat perangkat keras (tab floppy). Saya menduga ribuan file Anda berada di direktori yang berbeda dan Anda menginginkan laporan atau Anda memeriksa daftar master. (Lain penyalahgunaan Wayang hanya menunggu untuk terjadi).

Anda mungkin ingin Stéphane's perl tree-traversal dan untuk "bergabung" dengan daftar jika diperlukan (su juga akan menangkap eksekusi yang hilang pada direktori induk?). Jika surrogacy adalah masalah kinerja, apakah Anda melakukan ini untuk "sejumlah besar" pengguna? Atau apakah ini permintaan online? Jika ini merupakan persyaratan permanen yang berkelanjutan, mungkin sudah saatnya untuk mempertimbangkan produk pihak ketiga.

mckenzm
sumber
0

Anda dapat melakukan...

find / ! -type d -exec tee -a {} + </dev/null

... untuk daftar semua file yang pengguna tidak dapat menulis sebagaimana ditulis ke stderr dalam formulir ...

"tee: cannot access %s\n", <pathname>" 

... atau serupa.

Lihat komentar di bawah ini untuk catatan tentang masalah yang mungkin dimiliki pendekatan ini, dan penjelasan di bawah untuk alasan mengapa hal itu mungkin berhasil. Lebih waras lagi, Anda mungkin hanya perlu find file biasa seperti:

find / -type f -exec tee -a {} + </dev/null

Singkatnya, teeakan mencetak kesalahan ketika mencoba ke open()file dengan salah satu dari dua bendera ...

O_WRONLY

Terbuka hanya untuk menulis.

O_RDWR

Terbuka untuk membaca dan menulis. Hasilnya tidak terdefinisi jika flag ini diterapkan ke FIFO.

... dan bertemu ...

[EACCES]

Izin pencarian ditolak pada komponen awalan jalur, atau file ada dan izin yang ditentukan oleh oflag ditolak, atau file tidak ada dan izin menulis ditolak untuk direktori induk dari file yang akan dibuat, atau O_TRUNC adalah ditentukan dan izin tulis ditolak.

... sebagaimana ditentukan di sini :

The teeutilitas akan menyalin standar input ke output standar, membuat salinan di nol atau lebih file. Utilitas tee tidak akan buffer output.

Jika -aopsi tidak ditentukan, file output harus ditulis (lihat File Read, Write, and Creation ) ...

... POSIX.1-2008 membutuhkan fungsionalitas yang setara dengan menggunakan O_APPEND ...

Karena itu harus memeriksa dengan cara yang sama test -wtidak ...

-w pathname

Benar jika pathname menyelesaikan entri direktori yang ada untuk file yang izin untuk menulis ke file akan diberikan, sebagaimana didefinisikan dalam Baca File, Menulis, dan Pembuatan . Salah jika pathname tidak dapat diselesaikan, atau jika pathname memutuskan untuk entri direktori yang ada untuk file yang izin untuk menulis ke file tidak akan diberikan.

Mereka berdua memeriksa EACCESS .

mikeserv
sumber
Anda kemungkinan akan mengalami batas jumlah file yang terbuka secara bersamaan dengan pendekatan itu (kecuali jika jumlah file rendah). Waspadai efek samping dengan perangkat dan pipa bernama. Anda akan mendapatkan pesan kesalahan yang berbeda untuk soket.
Stéphane Chazelas
@ StéphaneChazelas - Semua sel - Saya pikir mungkin juga benar bahwa teeakan menggantung kecuali secara eksplisit terputus satu kali per menjalankan. Itu adalah hal terdekat yang bisa saya pikirkan [ -w... meskipun - efeknya harus dekat karena itu menjamin pengguna dapat MENGUNGKAPKAN file. Jauh lebih mudah daripada opsi mana pun paxdengan -oopsi format dan / atau -tuntuk mengecek EACCESS- tetapi setiap kali saya menyarankan paxorang tampaknya mengabaikannya. Dan, bagaimanapun, satu-satunya yang paxsaya temukan yang memenuhi std ada AST - dalam hal ini Anda mungkin juga menggunakan mereka ls.
mikeserv