Выяснение оболочки по умолчанию пользователя в сценарии оболочки

Это оболочка с тегами, но, честно говоря, я предпочитаю использовать язык сценариев с парсером. В данном случае perl с XML :: Twig .

Это выглядит примерно так:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

sub compare_by_identity {
   my ( $first, $second ) = @_;
   foreach my $identity ( $first->get_xpath('//Identity') ) {
      my $id = $identity->first_child_text('Id');

      print $id, "\n";
      my $compare_to =
        $second->get_xpath( "//Identity/Id[string()=\"$id\"]/..", 0 );
      if ($compare_to) {
         print "Matching element found for ID $id\n";
         foreach my $element ( $identity->children ) {
            my $tag  = $element->tag;
            my $text = $element->text;
            if ( not $element->text eq $compare_to->first_child_text($tag) ) {
               print "$id, $tag has value $text which doesn't match: ",
                 $compare_to->first_child_text($tag), "\n";
            }
         }
      }
      else {
         print "No matching element for Id $id\n";
      }
   }
}

my $first_file  = XML::Twig->new->parsefile('test1.xml');
my $second_file = XML::Twig->new->parsefile('test2.xml');

compare_by_identity( $first_file,  $second_file );
compare_by_identity( $second_file, $first_file );

Я явно сравниваю один элемент Identity за раз и проверяю, все ли поля в одном существуют в другом с одинаковым значением.

И затем обратное, потому что второй файл может иметь дополнительные записи.

9
23.05.2017, 15:40
7 ответов

Вы можете получить оболочку пользователя по умолчанию из среды следующим образом:

echo $SHELL

Но не таким образом:

echo $0

Последний вариант просто скажет вам, какую оболочку в данный момент использует ваш скрипт. Поэтому вам нужен первый вариант.

2
27.01.2020, 20:04

Коротко и безболезненно:

getent passwd <USER> | cut -d : -f 7
0
27.01.2020, 20:04

Поскольку getent не является стандартной командой в MacOS, вы можете использовать более низкий уровень getpwuid вызов, который проконсультируется со службами именования, для которых настроен аппарат. Для этого может потребоваться вызов perl или python , которые довольно распространены на большинстве Unix-подобных платформ

, например, это вернет оболочку для текущего пользователя:

perl -e '@x=getpwuid($<); print $x[8]'
5
27.01.2020, 20:04
$ finger $USER|grep -oP 'Shell: \K.*'
/bin/mksh
7
27.01.2020, 20:04

Переменная среды SHELL всегда расширяется до оболочки входа по умолчанию вызывающего пользователя (получает значение из / etc / passwd ).

Для любого другого пользователя вам необходимо выполнить некоторую обработку с помощью / etc / passwd , вот простой фрагмент awk :

awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd

Replace foobar ] с фактическим именем пользователя.

Если у вас есть ldap (или что-то подобное), используйте getent для получения базы данных вместо прямого синтаксического анализа / etc / passwd :

getent passwd | awk -F: -v user="foobar" '$1 == user {print $NF}'

или самый чистый подход, пусть getent выполнит синтаксический анализ (спасибо @Kusalananda):

getent passwd foobar | awk -F: '{print $NF}'
23
27.01.2020, 20:04

Может быть так:

   grep $USER </etc/passwd | cut -f 7 -d ":"
3
27.01.2020, 20:04

Позвольте мне расширить ответ @heemayl и объяснить магический awkкод, который он использует.

1. Просто помните о простых вещах:

Во-первых, это:

awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd

будучи на 100% правильным и, пожалуй, самым "правильным" ответом, его невозможно запомнить --вам придется выучить awkи затем каждый раз логически переписывать его с нуля. Что легко запомнить, так это то, что:оболочка по умолчанию для пользователя — это последнее поле в строке пользователя в файле "/etc/passwd", где поля разделены символом двоеточия :, и каждая строка в этом файле начинается с имени пользователя.

Теперь, зная это, просто подумайте :"хорошо, мне нужно найти строку с моим именем пользователя в /etc/passwd". Итак, сделайте это:

grep $USER /etc/passwd

ИЛИ (тот же эффект)

cat /etc/passwd | grep $USER

Вы получите что-то вроде этого:

my_username:x:1001:1001::/home/my_username:/bin/bash

Круто! Поэтому моя оболочка по умолчанию — это последнее поле, что означает все, что находится после последнего символа :. Это /bin/bash. Сделанный.

2. Объяснение этой awkкоманды:

awk -F: -v user="foobar" '$1 == user {print $NF}' /etc/passwd

awk— это язык сопоставления с образцом. Вы можете прочитать руководство по GNU awk или gawkздесь, которое является отличным справочником :https://www.gnu.org/software/gawk/manual/gawk.html

.
  1. /etc/passwdв конце находится файл, который нужно открыть и обработать с помощьюawk
  2. -F:предлагает изменить «разделитель поля» с пробела (по умолчанию )на :.
  3. Опция -vустанавливает переменную awk, которую вы называете здесь user, на «foobar»
  4. Теперь реальная программа awkхранится между одинарными кавычками. Это просто $1 == user {print $NF}. Помните, что:— это отдельный язык программирования! Он основан на сопоставлении шаблона или логической проверке { действие } . Он сканирует файл по одной «записи» (или строке, по умолчанию )за раз. $1— это первое поле в любой заданной строке, и помните,мы сказали, что поля разделены :, поэтому первое поле — my_username. Итак, $1 == userговорит: «Равно ли первое поле значению, хранящемуся в переменной awk user»? Если это так, выполните действие, указанное в фигурных скобках { }. Действие состоит в том, чтобы напечатать значение $NF, где внутренняя переменная NFсодержит «Число полей» для этой строки. Таким образом, количество полей равно 7, поскольку ::содержит 1 пустое поле между этими двумя двоеточиями. Поэтому $NFна самом деле $7или значение 7-го поля, которое для этого пользователя равно /bin/bash. Вот, магия шаблона -сопоставления языка, awk.
  5. Готово.

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

Что делать, если вы хотите установить или изменить оболочку по умолчанию для данного пользователя? Используйте chsh. man chshговорит, что он используется для «изменения оболочки входа». Вот как это использовать:

sudo chsh my_username --shell /path/to/my/shell

Пример :настроен на использование оболочки bash(мой предпочтительный выбор )по умолчанию:

sudo chsh my_username --shell /bin/bash

Еще один способ решить описанную выше проблему поиска оболочки по умолчанию, просто для удовольствия:

grep ^$USER: /etc/passwd | grep -Eo ':([^:]*)$' | tr -d ':'

Краткое описание :находим строку с пользователем, находим в конце путь :/my/shell, удаляем из него символ :.

Дополнительные awkучебные ресурсы:

  1. См. несколько тестовых файлов hello world и синтаксиса для awk, которые я написал здесь:https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awk
  2. Исследование git diffn, например, здесь . Примечание:git diffn— это оболочка, которую я написал вокруг git diff, чтобы показать номера строк.
2
27.05.2020, 07:54

Теги

Похожие вопросы