{ echo 'exec <&3 3<&-; id' | sh -si; } 3<&0
Кажется, работает с большинством
sh
реализаций. Мы просим интерактивную оболочку с-i
(, в противном случае некоторые оболочки отключили бы ее на том основании, что стандартный ввод не является терминальным устройством ), начните с того, что стандартный ввод оболочки является каналом, но затем с помощьюexec <&3
проинструктируйте его изменить его на исходный (внешний )стандартный ввод, который мы ранее сохранили в файловом дескрипторе 3 с помощью3<&0
.Мы делаем это до запуска
id
, но все еще в той же командной строке , так что стандартный ввод восстанавливается и дляid
. Дляid
это не имеет значения, так как он не читает свой стандартный ввод, но это будут интерактивные команды, такие как редакторы или оболочки.Что касается того, почему вы видите то, что вводите
(echo id | cat) | sh
. Похоже, ваша реализацияsh
, которая кажется очень старой версиейbash
, работает в интерактивном режиме. Вы можете видеть это по тому факту, что он выдает подсказку, как если бы использовалось-i
.Затем он реализует свой собственный строковый редактор, но не может отключить собственный строковый редактор tty-устройства (, потому что его stdin — это конвейер, а не tty-устройство ), поэтому вы получаете эхо того, что вы вводите, дисциплину строки устройства tty, и как только вы нажмете ввод,
cat
сразу увидит все содержимое этого строкового буфера, включая конечную новую строку, из канала, который он сразу же записывает вbash
, аbash
выводитecho
этого как часть собственного линейного редактора.Я подозреваю, что если бы вы:
stty -icanon -echo; (echo id; cat) | sh; stty sane
Вы получите лучшее поведение и, возможно, сможете использовать функции редактирования строки readline, так как
bash
будет получать каждый введенный вами символ непосредственно по мере его поступления.Чтобы узнать о других параметрах автоматического запуска команды перед тем, как пользователь примет интерактивную оболочку, см.:
Попробуйте
$ find. -name "[A-Z]*" -type d |
while read FN
do echo sapcontrol -nr ${FN##*[A-Z]} -function GetSystemInstanceList
done
sapcontrol -nr 00 -function GetSystemInstanceList
sapcontrol -nr 02 -function GetSystemInstanceList
Если вам нужны только последние два символа из нескольких конкретных папок, то есть также:
echo ${VAR1:(-2)}
или даже (расширение @RudiC )и выбор каталогов без каких-либо цифр, кроме двух последних цифр с расширением GNUfind
find. -type d -regex "[^0-9]*[0-9][0-9]" -exec sh -c 'echo sapcontrol -nr ${1:(-2)} -function GetSystemInstanceList' sh {} \;
Вы можете назначить вывод переменной, затем вы можете использовать сопоставление с образцом, например:
VAR1=ABCD01
echo ${VAR1##*[[:alpha:]]}
Это удалит из переменной все буквенные символы и напечатает «01».