Podczas próby zmodyfikowania pliku bez uprawnień do zapisu pojawia się błąd:
> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing nie pomaga, ponieważ uruchamia polecenie jako root, ale powłoka obsługuje stdout przekierowujący i otwiera plik tak jak ty:
> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Czy istnieje prosty sposób przekierowania standardowego pliku do pliku, do którego nie masz uprawnień do zapisu, oprócz otwarcia powłoki jako root i manipulowania plikiem w ten sposób?
> sudo su
# echo test > /tmp/foo
shell
permissions
io-redirection
sudo
io
Michał Mrożek
źródło
źródło
chown
zmieniałem właściciela; to tylko przykładOdpowiedzi:
Tak, używając
tee
. Tak sięecho test > /tmp/foo
stajeMożesz także dołączyć (
>>
)źródło
echo test | sudo tee /tmp/foo > /dev/null
Aby zamienić zawartość pliku na wynik
echo
(np.>
Operator przekierowania powłoki).Aby zapisać do pliku (na początku możesz używać
seek
wyjścia z różnymi przesunięciami) bez obcinania (jak1<>
operator powłoki Bourne'a):Aby dołączyć do pliku (jak
>>
) za pomocą GNUdd
:Zobacz także GNU
dd
,conv=excl
aby uniknąć blokowania istniejącego pliku (jakset -o noclobber
w przypadku powłok POSIX), aconv=nocreat
na odwrót (aktualizuj tylko istniejący plik).źródło
echo test | sudo tee /tmp/foo >/dev/null
aby odrzucić dane wyjściowe.dd
jest niewiarygodne, chyba że używasz niejasnych opcji tylko GNUiflag=fullblock oflag=fullblock
, które usuwają elegancję tej odpowiedzi. Będę się trzymaćtee
.dd
może być dość niebezpieczny (jeśli nie mówiąc: niszczący), jeśli popełniony zostanie tylko niewielki błąd. Tak więc dla nowych użytkowników wolałbymtee
metodę przebywania na bezpiecznym brzegu.dd of=file
samego (bezcount
/skip
...), jest niezawodny.iflag=fullblock
nie jest potrzebne, ponieważ tutajdd
zapisuje na wyjściu to, co przeczytał na wejściu. Nie ma znaczenia, czy nie były to pełne bloki.tee
jest prawdopodobnie najlepszym wyborem, ale w zależności od twojej sytuacji coś takiego może wystarczyć:źródło
eval
zamiast prostegosh -c
; -i, co zmieni twój działający katalog; uruchomienie całej komendy jako root, co może zmienić jej zachowanie lub wprowadzić niepotrzebne ryzyko. dlaczego to kiedykolwiek zyskało aprobatę?Chociaż zgadzam się, że
| sudo tee
jest to sposób kanoniczny, czasami sed (tutaj przy założeniu GNUsed
) może działać:-i
modyfikuje plik na miejscu.1i
oznacza wstaw przed wierszem 1.$a
oznacza dołącz po ostatnim wierszu.Lub skopiuj do xclipboard:
źródło
sed -i
tak naprawdę nie modyfikuje pliku na swoim miejscu - tworzy plik tymczasowy i zmienia nazwę podczas wychodzenia. Więc nie będziesz w stanie zrobić czegoś takiego jaktail -f ...
na oryginalnym pliku i zobaczyć, jak dane wyjściowe są używanesed -i ...
podczas działania potoku-i creates a new file of same name
może jest coś bardziej kompaktowego? Chyba lubięin place
, bo to wyjaśniai
. Strona gnu-sed również nazywa to na miejscu, a długa flaga jest--in-place
.Kopałem sobie w głowie pomysły na podobny problem i wymyśliłem następujące rozwiązania:
sudo uncat
gdzieuncat
jest program, który czyta standardowe dane wejściowe i zapisuje je do pliku o nazwie podanej w wierszu poleceń, ale jeszcze nie napisałemuncat
.sudocat
wariantsudoedit
, którego jeszcze nie napisałem, który czyścisudo cat
lubsudo uncat
.lub tę małą sztuczkę korzystania
sudoedit
z EDYTORA, który jest skryptem powłokiktóre mogą być powoływane jako albo
|sudo ./uncat file
albo| EDITOR=./uncat sudoedit
ale ma ciekawe efekty uboczne.źródło
cat
pobiera listę plików do con kota inate zatem UNCAT powinien wziąć listę plików do un con kota inate do. Będzie musiał użyć magii, aby zdecydować, ile umieścić w każdym pliku. Alternatywna nazwa obejmujądog
,to-file
,redirect
.uncat
, gdybym miałtee
.tee
ma tę trywialną wadę, że zapisuje swoje standardowe wejście na standardowe wyjście - co jest trywialnie zmniejszone przez przekierowanie standardowego wejścia na/dev/null
. Inne alternatywy todd of=/tmp/foo
(wspomniane w innej odpowiedzi), która zapisuje informacje o statusie do stderr icp /dev/stdin /tmp/foo
.Użyj gąbki z pakietu moreutils. Ma tę zaletę, że nie pisze na standardowe wyjście.
Użyj opcji -a, aby dołączyć do pliku zamiast nadpisywać go.
źródło
/dev/null
jeśli byłby to problemBłąd pochodzi z kolejności, w jakiej powłoka wykonuje różne czynności.
Przekierowanie jest obsługiwane przed uruchomieniem powłoki
sudo
, a zatem odbywa się za zgodą użytkownika, nad którym obecnie pracujesz. Ponieważ nie masz uprawnień do zapisu, aby utworzyć / skrócić cel przekierowania, otrzymujeszpermission denied
błąd z powłoki.Rozwiązaniem jest zagwarantowanie, że plik wyjściowy zostanie utworzony zgodnie z tożsamością podaną przez użytkownika
sudo
, np .tee
:źródło