В, 'в то время как IFS = чтение..', почему IFS не имеет никакого эффекта?

В то время как возможно переименовать пользователя, и usermod сделает часть задания, это, довольно вероятно, доставит неприятности. Вот список мест, где имя пользователя может появиться; я не утверждаю, что этот список является исчерпывающим.

  • Пользовательская запись в /etc/passwd и связанные файлы (например. /etc/shadow, /etc/master.passwd).
  • Записи группы в /etc/group/etc/gshadow).
  • Возможно записи в /etc/sudoers.
  • Системный почтовый ящик, обычно /var/mail/$USER или /var/spool/mail/$USER.
  • crontab, обычно /var/spool/cron/crontabs/$USER
  • В at задания (/var/spool/cron/atjobs/*)

Корневой каталог, вероятно, появится еще в большем количестве мест. Много приложений пишут полные пути в различных точечных файлах. Если Вы решаете переименовать корневой каталог также (в то время как нет никакого требования того пользователя aliceкорневой каталог быть /home/alice, наличие его быть /home/bob сбивало бы с толку), необходимо будет заботиться о тех. Глобальная замена будет работать на большинство приложений, но я не делаю обещаний. Если возможно, сохраните старое название корневого каталога как символьную ссылку на переименованный каталог.

12
17.08.2011, 22:58
2 ответа

(Извините, долгое объяснение)

Да, IFS переменная в while IFS=" " read; do … не имеет никакого эффекта на остальную часть кода.

Позвольте нам сначала точный что функции командной строки оболочки два различных видов переменных:

  • переменные оболочки (которые только существуют в оболочке и локальны для оболочки),
  • переменные среды, которые существуют для каждого процесса. Они обычно сохраняются на fork() и exec(), таким образом, дочерние процессы наследовали их.

Когда Вы называете команду с:

  A=foo B=bar command

команда выполняется в в среде где (среда) переменная A установлен на foo и B установлен на bar. Но с этой командной строкой, текущими переменными оболочки A и B оставлены без изменений.

Это отличается от:

A=foo; B=bar; command

Здесь, переменные оболочки A и B определяются и команда выполняется без переменных среды A и B определенный. Значения A и B недоступны от command.

Однако, если некоторые переменные оболочки export- редактор, соответствующие переменные среды синхронизируются с их соответствующими переменными оболочки. Пример:

export A
export B
A=foo; B=bar; command

С этим кодом обе переменные оболочки и переменные среды оболочки установлены на foo и bar. Так как переменные среды наследованы подпроцессами, command сможет получить доступ к их значениям.

Переходить назад к Вашему исходному вопросу, в:

IFS='a' read

только read затронут. И на самом деле, в этом случае, read не заботится о значении IFS переменная. Это использует IFS только, когда Вы просите, чтобы строка была разделена (и сохранена в нескольких переменных), как в:

echo "a :  b :    c" | IFS=":" read i j k; \
    printf "i is '%s', j is '%s', k is '%s'" "$i" "$j" "$k"

IFS не используется read если это не называют с аргументами. (Редактирование: Это не точно верно: пробельные символы, т.е. пространство и вкладка, существующая в IFS всегда игнорируются в начале/конце входной строки.)

17
27.01.2020, 19:54
  • 1
    Какое большое объяснение! Это настолько просто! Я не был смущен той 'никакой точкой с запятой' синтаксис в течение многих месяцев; и это - просто случай его означающий локальную переменную!.. rozcietrzewiacz открыл трассу для меня (большой успех) в другом вопросе..., и Вы только что поместили обледенение на пирог... Я бодрствовал всю ночь на этом, и это, конечно, стоило того для таких хороших и четких ответов!..Спасибо.. –  Peter.O 18.08.2011, 00:04
  • 2
    Uhm. Я должен был несколько раз читать тот комментарий редактирования, прежде чем я получил его – Вы означаете говорить, что пробельные символы, которые присутствуют в $IFS удалены в начале/конце входной строки, я предполагаю? (Который является, как это работает.) –  zrajm 28.07.2014, 08:22
  • 3

Поместите его простой, необходимо читать больше чем в одну переменную за один раз для IFS=<something> read ... создайте, чтобы иметь видимый эффект в Вашем examples1.

Вы пропускаете объем read в примерах. Нет никакой модификации IFS в цикле в Ваших тестовых сценариях. Позвольте мне указывать точно, где делает вторую IFS, имеют ее эффект в каждой из Ваших строк:

 IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=b   read; do echo ...
                                                      ^      ^
                                                      |      |
                                          from here --'       `- to here :)

Это так же, как с любой программой, выполненной в оболочке. Переменная, которую Вы (ре) определяете в командной строке, влияет на выполнение программы. И только что (так как Вы не экспортируете). Поэтому сделать использование переопределенных IFS в такой строке необходимо было бы спросить read присваивать значения больше чем одной переменной. Взгляните эти примеры:

 $ data="a  b   c"
 $ echo "$data" | while           read A B C; do echo \|$A\|$B\|\|$C\|; done
 |a|b||c|
 $ echo "$data" | while IFS=      read A B C; do echo \|$A\|$B\|\|$C\|; done
 |a b c||||
 $ echo "$data" | while IFS='a'   read A B C; do echo \|$A\|$B\|\|$C\|; done
 || b c|||
 $ echo "$data" | while IFS='ab'  read A B C; do echo \|$A\|$B\|\|$C\|; done
 || || c|

1, Как я только что узнал от Gilles, могло бы на самом деле быть преимущество установки IFS='' (пробел) при чтении только одного поля: это избегает усечения пробела в начале строки.

8
27.01.2020, 19:54
  • 1
    Хороший..Спасибо... Я получил его на этот раз.. и я люблю Ваш эскиз :) –  Peter.O 17.08.2011, 23:50
  • 2
    OK, теперь я прочитал Ваш комментарий, которые видят, что Вы не замечаете мой ответ на ту проблему в другом вопросе. Возможно, Вы могли просто вернуться другой и удалить это, так как это действительно - один общий вопрос? –  rozcietrzewiacz 17.08.2011, 23:52
  • 3
    Да, эти два вопроса действительно имеют связанную тему, но заголовок другого - "Почему IFS= read используемый в предпочтении только к сбросу переменной среды IFS". У меня не было осведомленности, затем, что локальные переменные могли быть установлены вызывающей стороной команды. Это было ответом на тот вопрос. Это действительно развивалось далее к обращению к основному моменту этого вопроса, но к тому времени, когда я понял, что, уже задал этот вопрос... Возможно, эти два вопроса так же подобны как два sed вопросы, таким образом, мое чувство это для хранения его как есть... Больше заголовков для сотрудников Google к Google. –  Peter.O 18.08.2011, 00:47

Теги

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