Это оболочка с тегами, но, честно говоря, я предпочитаю использовать язык сценариев с парсером. В данном случае 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 за раз и проверяю, все ли поля в одном существуют в другом с одинаковым значением.
И затем обратное, потому что второй файл может иметь дополнительные записи.
Вы можете получить оболочку пользователя по умолчанию из среды следующим образом:
echo $SHELL
Но не таким образом:
echo $0
Последний вариант просто скажет вам, какую оболочку в данный момент использует ваш скрипт. Поэтому вам нужен первый вариант.
Коротко и безболезненно:
getent passwd <USER> | cut -d : -f 7
Поскольку getent
не является стандартной командой в MacOS, вы можете использовать более низкий уровень getpwuid
вызов, который проконсультируется со службами именования, для которых настроен аппарат. Для этого может потребоваться вызов perl
или python
, которые довольно распространены на большинстве Unix-подобных платформ
, например, это вернет оболочку для текущего пользователя:
perl -e '@x=getpwuid($<); print $x[8]'
Переменная среды 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}'
Позвольте мне расширить ответ @heemayl и объяснить магический awk
код, который он использует.
Во-первых, это:
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
. Сделанный.
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
/etc/passwd
в конце находится файл, который нужно открыть и обработать с помощьюawk
-F:
предлагает изменить «разделитель поля» с пробела (по умолчанию )на :
. -v
устанавливает переменную awk, которую вы называете здесь user
, на «foobar» awk
хранится между одинарными кавычками. Это просто $1 == user {print $NF}
. Помните, что:— это отдельный язык программирования! Он основан на сопоставлении шаблона или логической проверке { действие } . Он сканирует файл по одной «записи» (или строке, по умолчанию )за раз. $1
— это первое поле в любой заданной строке, и помните,мы сказали, что поля разделены :
, поэтому первое поле — my_username
. Итак, $1 == user
говорит: «Равно ли первое поле значению, хранящемуся в переменной awk user
»? Если это так, выполните действие, указанное в фигурных скобках { }
. Действие состоит в том, чтобы напечатать значение $NF
, где внутренняя переменная NF
содержит «Число полей» для этой строки. Таким образом, количество полей равно 7, поскольку ::
содержит 1 пустое поле между этими двумя двоеточиями. Поэтому $NF
на самом деле $7
или значение 7-го поля, которое для этого пользователя равно /bin/bash
. Вот, магия шаблона -сопоставления языка, awk
. Что делать, если вы хотите установить или изменить оболочку по умолчанию для данного пользователя? Используйте 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
учебные ресурсы:awk
, которые я написал здесь:https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/tree/master/awkgit diffn
, например, здесь . Примечание:git diffn
— это оболочка, которую я написал вокруг git diff
, чтобы показать номера строк.