LinuxCamp | DevOps
13.7K subscribers
286 photos
14 videos
395 links
Обо мне: C/C++/Linux эксперт. Говорим про разработку, Linux, DevOps, сети и администрирование.

Админ (реклама): @XoDefender
Чат: @linuxcamp_chat

Менеджер: @Spiral_Yuri
Биржа: https://telega.in/c/linuxcamp_tg

РКН: https://clck.ru/3RWA3C
Download Telegram
Разница между su и su -

Ни для кого не секрет, что Linux - система, с которой можно работать от разных пользователей. Сегодня я запускаю сессию от Паши, завтра от Пети.

Когда вы в сессии открываете терминал, стартует оболочка, которая подстраивает окружение под конкретного юзера: выполняет скрипты, определяет переменные.

Бывает, приходится, работая в сессии одного пользователя, переключиться на другого, например, чтобы использовать ресурсы, ограниченные правами доступа. Для этого мы используем команду "su" (substitute user), которая позволяет сменить пользователя в текущей оболочке:


$ su vasya


После того, как мы выполним команду, создастся дочерняя оболочка, которая переймет все переменные окружения родителя, определит пользовательские (USER, HOME ...) и выполнит локальные "Васины" скрипты: /home/vasya/.bashrc и т.д.:


$ export USER1VAR="vasya"

$ su xoadmin
$ printenv | grep USER
USER=xoadmin
USER1VAR=vasya


Чет какая-то каша выходит. Половина Васиных переменных, половина юзера xoadmin. Такой способ полезен, когда нам нужно быстро поменять пользователя и не требуется его окружение в изначальном виде.

Если нужно полностью воссоздать среду, как при чистом входе в систему, следует использовать "su -":


$ su - xoadmin


Окружение родителя мы не наследуем и запускаем оболочку типа "login shell", которая выполнит дополнительные скрипты инициализации "/etc/profile", "~/.bash_profile". Подробнее про типы оболочек говорили вот тут, а про этапы их инициализации тут.

Также, когда мы используем "su -", наш рабочий каталог переключается на домашний для целевого пользователя. Мелочь, но факт:


$ pwd
/home/vasya/Music
$ su - xoadmin
$ pwd
/home/xoadmin


LinuxCamp | #shell
👍78🔥15❤‍🔥86
Стрелка за 200 в работе с файловой системой

Представим такой рабочий процесс, когда нам нужно перемещаться между 4 каталогами, расположенными по совершенно разным путям.

Использовать "cd -" не вариант, т.к. оболочка запоминает только 1 прошлый каталог. Можно использовать CDPATH, но тогда нужно запоминать названия директорий, с которыми работаем.

Команды оболочки pushd, popd и dirs позволяют обойти это ограничение. Предположим, вы создаете локальный сайт и работаете с ресурсами:


/var/www/html
/etc/apache2
/etc/ssl/certs
~/Web/src


Быстро переключаться между ними можно с помощью функции оболочки - "стеком каталогов".

Стек каталогов — это список директорий, которые вы посетили и решили отслеживать в текущем экземпляре оболочки. Изначально он содержит только текущий путь.

Просмотреть стек можно, используя команду dirs:


$ dirs
/etc/ssl/certs /etc/apache2 /var/www/html ~/Web/src


Вывод команды можно напечатать столбцом "-p":


$ dirs -p
/etc/ssl/certs
/etc/apache2
...


А можно и пронумеровать "-v". Это нам позволит вдальнейшем удобнее переключаться между каталогами:


$ dirs -v
0 /etc/ssl/certs
1 /etc/apache2
...


Вы управляете стеком, выполняя две операции: pushing и popping (есть, кста, такой стиль танца - весело выглядит).

Pushing каталога добавляет его в начало списка (вершину стека) и переходит в него:


$ pushd /etc/apache2
/etc/apache2 /var/www/html


Для того, чтобы только добавить каталог в стек и не переходить на него, нужно использовать флаг "-n".

Popping удаляет верхний каталог из стека и возвращает нас на следующий за ним:


$ popd
/var/www/html


Если хотим полностью очистить стек, тогда либо выполняем "dirs -c", либо зовем popd до тех пор, пока не увидим:


$ popd
bash: popd: directory stack empty


Принцип работы со стеком заключается в том, что мы добавляем туда каталоги, после чего прыгаем по ним, используя аргументы для pushd и popd, которые рассмотрим далее.

LinuxCamp | #shell
👍39🔥17❤‍🔥3👎1
Практика использования: pushd, popd, dirs

И так, вернемся к задаче, над которой начали работать тут. Для того, чтобы быстро переключаться между 4 каталогами, нужно сначала добавить их в стек. Текущий будет самым левым (верхним):


$ pushd /var/www/html
/var/www/html ~/Web/src

$ pushd /etc/apache2
/etc/apache2 /var/www/html ~/Web/src

$ pushd /etc/ssl/certs
/etc/ssl/certs /etc/apache2 /var/www/html ~/Web/src


Команда pushd без аргументов меняет местами два верхних каталога в стеке и переходит к новому верхнему. Давайте несколько раз переместимся между "/etc/ssl/certs" и "/etc/apache2":


$ pwd
/etc/ssl/certs

$ pushd
/etc/apache2 /etc/ssl/certs /var/www/html ~/Web/src

$ pushd
/etc/ssl/certs /etc/apache2 /var/www/html ~/Web/src


Что делать, если нужно перейти в другие каталоги стека, помимо двух верхних? pushd и popd принимают целочисленные аргументы для данной задачи. Давайте для наглядности выведем текущий стек в столбец:


$ dirs -v
0 /etc/ssl/certs
1 /etc/apache2
2 /var/www/html
3 ~/Web/src


Команда "pushd +N" сдвигает N каталогов с вершины стека в самый низ, а затем переходит к новому верхнему. Если нужно попасть в "/var/www/html" и сохранить структуру стека, используем:


$ pushd +2
/var/www/html ~/Web/src /etc/ssl/certs /etc/apache2


Отрицательный аргумент (-N) сдвигает каталоги в противоположном направлении. Чтобы перейти к каталогу в нижней части стека, можно либо сдвинуть все, кроме последнего, либо просто использовать "pushd -0":


$ dirs
/etc/apache2 /etc/ssl/certs ~/Web/src /var/www/html

$ pushd -0
/var/www/html /etc/apache2 /etc/ssl/certs ~/Web/src


Можно также удалять каталоги из стека, используя popd с аргументом. Команда "popd +N" удаляет каталог, расположенный на позиции N, из стека. Отрицательный аргумент (-N) означает отсчет снизу. Подсчет начинается с нуля, поэтому "popd +1" удаляет второй каталог сверху:


$ dirs
/var/www/html /etc/apache2 /etc/ssl/certs ~/Web/src

$ popd +1
/var/www/html /etc/ssl/certs ~/Web/src

$ popd +2
/var/www/html /etc/ssl/certs


Будьте аккуратны и внимательны. Если вы используете команду cd, то самый верхний элемент стека затрется на текущий активный каталог. Эту проблему мы научимся решать в пятницу)

LinuxCamp | #shell
🔥24👍165
Команда «ой, я забыл pushd»

Предыдущие посты по стеку каталогов: тут и тут.

Предположим, вы перемещаетесь между несколькими директориями с помощью pushd, а потом случайно запускаете cd и теряете первый элемент стека:


$ dirs
~/Web/src /var/www/html /etc/apache2

$ cd /etc/ssl/certs

$ dirs
/etc/ssl/certs /var/www/html /etc/apache2


Команда cd заменила каталог "~/Web/src" на "/etc/ssl/certs". Не волнуйтесь, чтобы все это дело пофиксить, нужно запустить pushd с дефисом:


$ pushd -
~/Web/src /etc/ssl/certs /var/www/html /etc/apache2


Команда работает практически аналогично "cd -": добавляет прошлый активный каталог в стек и переходит на него. Теперь к нам вернется потерянный каталог и сохранится тот, в который мы перешли через cd.

Если мы через cd куда-то перешли, осознали проблему, но менять каталог не хотим, используем pushd дважды. Для удобства еще и alias определим:


$ pushd -
~/Web/src /etc/ssl/certs

$ pushd
/etc/ssl/certs ~/Web/src


alias slurp='pushd - && pushd'


Такой прием, конечно, не поможет, если мы несколько раз через cd походили по разным местам. Тут нужно вовремя раздуплиться, иначе придется вводить полный путь.

LinuxCamp | #shell
🔥24👍15❤‍🔥31
`>`, `2>`, `&1`, `2>&1` - что это вообще такое?

Эти команды и символы часто можно встретить в терминале или скриптах. Разбираем по порядку, что означает каждый знак, куда уходит вывод и почему от порядка зависит результат.

Стандартные потоки


1 - stdout (нормальный вывод)
2 - stderr (ошибки)


Каждая команда в Linux работает с тремя потоками. Читает из stdin, пишет результат в stdout и выводит ошибки в stderr. Перенаправление (>, 2>, 2>&1) - это способ указать, куда именно должен идти каждый поток: в файл, в терминал или в никуда.

Символ '>' - направить вывод в файл


echo "hello" > log.txt


'>' создаёт (или перезаписывает) файл и отправляет туда стандартный вывод. Чтобы не затирать файл используйте '>>', он вставляет в конец:


echo "new line" >> log.txt


Символ '2>' - то же самое, но для ошибок


command 2> errors.txt


Здесь '2' - это номер потока stderr. Ошибки уйдут в errors.txt, а обычный вывод останется в терминале.

Объединение потоков: '2>&1'


command > all.txt 2>&1


'2>&1' значит отправить ошибки ('2') туда же, куда идёт обычный вывод ('1'). Порядок важен! Если написать наоборот (2>&1 > all.txt), ошибки всё равно пойдут в консоль, потому что в момент перенаправления stdout ещё не указывает на файл.

Сокращённая запись: '&>'


command &> all.txt


Эквивалент предыдущей команды, оба потока в один файл. Работает только в bash и zsh. Если ваш скрипт должен выполняться в sh или dash, используйте классическую форму.

/dev/null - "чёрная дыра"


command > /dev/null 2>&1


Команда выполняется, но вывод и ошибки никуда не сохраняются. Удобно для cron-задач, но не для отладки.

Вывод

Понимание потоков позволит писать устойчивые shell-скрипты и не терять данные.

LinuxCamp | #shell
👍6118🔥10🦄3🎉1