Czy istnieje sposób, aby powiedzieć sudo, aby ustawiła moją nazwę użytkownika jako właściciela plików utworzonych zamiast root?

19

Jeśli to zrobię sudo cp /etc/foo.txt ~/foo.txt, nowy plik zostanie utworzony rootjako właściciel.

W tej chwili nie widzę innego rozwiązania niż użycie dwóch ostatnich poleceń (w lscelu wyjaśnienia przypadku użycia):

belmin@server1$ ls /etc/foo.txt
>  -rw------- 1 root root 3848 Mar  6 20:35 /etc/foo.txt
>
belmin@server1$ sudo cp /etc/foo.txt ~/foo.txt
belmin@server1$ sudo chown belmin: $_

Wolałbym:

  1. Robienie tego za pomocą jednego sudopolecenia.
  2. Nie muszę określać mojego obecnego użytkownika (może używasz zmiennej?).
Belmin Fernandez
źródło
sudo cat /etc/foo.txt > ~/foo.txt. Pliki mogą być odczytywane tylko przez roota z jakiegoś powodu, więc pamiętaj o tym, aby kopie były czytelne dla użytkowników innych niż root.
jw013,

Odpowiedzi:

32

Użyj installzamiast cp:

sudo install -o belmin /etc/foo.txt ~/foo.txt
Jenny D.
źródło
Nie byłam tego świadoma install. Dziękuję Ci.
Belmin Fernandez,
4
@BelminFernandez: Aby uwzględnić drugą preferencję:sudo install -o "$USER" /etc/foo.txt ~/foo.txt
Wstrzymano do odwołania.
14

Z POSIX kompatybilnycp można sudo cp -p foo barby zachować następujące metadane plików podczas kopiowania:

  • Czas dostępu
  • Czas modyfikacji
  • Identyfikator użytkownika
  • Identyfikator grupy
  • Tryb

Jeśli chcesz ustawić innego użytkownika , najlepsze jest rozwiązanie JennyD .

l0b0
źródło
2
Działa to tylko wtedy, gdy oryginalny plik jest własnością użytkownika docelowego.
Jenny D,
4
Zakładam, że osoba uruchamiająca sudo nie jest właścicielem oryginalnego pliku, w przeciwnym razie nie musiałaby używać sudo.
EightBitTony,
@EightBitTony Nie musisz sudokopiować pliku, którego nie jesteś właścicielem. W końcu potrzebujesz tylko dostępu do odczytu .
l0b0
Tak, z mojej strony błędnie - ale zakładam, że dany identyfikator użytkownika również nie może odczytać pliku, ponieważ nadal nie potrzebują sudo. Musimy więc założyć, że ID użytkownika, który ma być właścicielem końcowego pliku, nie ma dostępu do oryginalnego pliku. Tak czy inaczej, nie jest to sudo „problem”. Twoja odpowiedź sugeruje, że zachowanie właściciela nie jest pożądane.
EightBitTony,
2
Teoretycznie możliwe jest, że plik jest własnością użytkownika docelowego, ale znajduje się w katalogu, do którego użytkownik docelowy nie ma uprawnień. Ale to mało prawdopodobne :-)
Jenny D.
8

Jeśli zrobisz:

sudo cat /etc/foo.txt > ~/foo.txt

Wtedy ~/foo.txtbędzie otwarta przez powłokę jako ciebie (tak utworzonego z poświadczeniami), a następnie sudozostanie wykonany z stdout przekierowany do tego.

Ostatecznie plik będzie własnością użytkownika.

Takie podejście pomaga również ograniczyć liczbę wykonywanych zadań root. Tutaj rootużywa tylko swojego przywileju do otwierania /etc/foo.txt, nie robi rzeczy potencjalnie szkodliwych (otwórz plik do pisania, który mógłby mieć złe konsekwencje, gdyby ~/foo.txtna przykład był dowiązaniem symbolicznym).

Stéphane Chazelas
źródło
2
Zakłada się, że użytkownik może pisać do katalogu docelowego.
Johan
3

Za pomocą sudoprzełączasz się na innego użytkownika. To jest sedno polecenia. Zakładam, że nie masz regularnego dostępu do pierwszego pliku, więc musisz być innym użytkownikiem ( rootw tym przypadku), aby uzyskać dostęp.

Nie ma sposobu, aby sudosobie z tym poradzić, ponieważ wszystko, co sudorobisz, to przełączenie się do innego użytkownika w celu wykonania polecenia.

Będziesz musiał

  1. nadal używaj dwóch poleceń (lub jednego polecenia złożonego)
  2. znajdź inne polecenie (np. zainstaluj, widoczne w innej odpowiedzi)
  3. lub napisz skrypt i uruchom go za pomocą sudo.
EightBitTony
źródło
1

Sudo tworzy zmienną środowiskową „SUDO_USER”, której można użyć do znalezienia użytkownika, który się zalogował (a właściwie który uruchomił Sudo).

Zakładając, że Sudo jest rootem (możliwe jest użycie Sudo w celu uzyskania dostępu również do innych użytkowników), możesz napisać skrypt automatyzujący następujące dwa kroki.

cp source target
chown $SUDO_USER target

(To nie zadziała, jeśli sudo zostanie zalogowane do użytkownika innego niż root, ponieważ tylko root może rozdawać pliki.)

Automatyzacja będzie trochę pracochłonna. Jeśli źródłem jest pojedynczy plik, a celem nie jest katalog, oznacza to, że praca jest zakończona. Zakładam, że zadałeś pytanie, ponieważ problem jest tylko realnym problemem w bardziej złożonych sytuacjach, np. Podczas robienia czegoś takiego:

cp /path/source/some*files /path/target/directory/

Można napisać skomplikowany skrypt, aby dowiedzieć się, jakie pliki i jakie katalogi są przekazywane, które wcześniej istniały, które faktycznie zostały nadpisane, i aby zmienić własność tylko pomyślnie skopiowanych plików.

Ta praca została już wykonana. Możesz użyć cpio- Po sudo do rootowania, użyj cpio, aby skopiować pliki. cpio potrzebuje listy plików do skopiowania, więc jest to proces dwuetapowy. Poniżej używam lsdo generowania listy plików do skopiowania.

ls /path/source/some*files | cpio -pdm --owner $SUDO_USER /path/target/directory/

Te -pdmśrodki „tryb Passthrough, tworzenie katalogów, ile potrzeba, utrzymania czasy modyfikacji pliku”

--owner $SUDO_USER" powoduje, że określony użytkownik jest właścicielem plików.

Ostatnim operandem jest katalog, w którym cpio musi przechowywać pliki.

Aby dowiedzieć się więcej o niesamowitości CPIO , przejdź do strony podręcznika CPIO tutaj

Jest to również możliwe w jednym poleceniu sudo. Zakładając, że twój użytkownik ma prawa dostępu do plików, używaj sudo tylko do części cpio, tak jak to:

ls /path/source/some*files | cpio -pdm --owner $USER /path/target/directory/

W powyższym przypadku używam $ USER zamiast $ SUDO_USER, ponieważ jest on obliczany przed uruchomieniem Sudo. Alternatywnie, jeśli użytkownik nie ma dostępu do listy plików, umieść go w skrypcie opakowania i użyj sudo, aby uruchomić opakowanie. Może to stać się trudniejsze, ale w najprostszym przypadku Opakowanie przyjmuje dwa argumenty, źródło i cel.

To idzie do opakowania „cp_as_user”:

ls $1 | cpio -pdm --owner $SUDO_USER $2

Następnie użyj opakowania w następujący sposób:

sudo cp_as_user "/ path / to / some * files" / path / to / target / directory

Johan
źródło