Файл .profile
не является файлом конфигурации оболочки, это файл настроек сессии входа. Он читается только оболочкой, запущенной при входе в систему, а не другими интерактивными оболочками, запущенными в рамках вашей сессии входа в систему.
ksh
не имеет специального файла настроек как такового, но он рассматривает переменную $ENV
как путь к файлу настроек для интерактивных сеансов оболочки.
Поэтому вы можете добавить что-то вроде:
ENV="$HOME/.kshrc" export ENV
в ~/.profile
и:
alias 'l=ls -lrt'
в ~/.kshrc
.
Изменение вступит в силу только при следующем входе в систему.
В общем случае это невозможно, так как:
Each command in a pipeline is executed in its own subshell
(из руководства bash).
Если команда отправки задерживается достаточно долго, есть шанс, что вы сможете ее найти. Ниже приведен пример сценария «получатель»; он берет столбец NODE из lsof
, который соответствует стандартному вводу получателя, затем ищет в более широком выводе lsof
процесс, чей стандартный вывод NODE соответствует:
#!/bin/sh
# look for f0 and get its node
node=$(lsof -p "$$" -Ffi | awk '/^p/ { node=""; } /^f0$/ { getline; node=substr($0, 2); exit; } END { print node }')
# run lsof and get the pid(s) with f1 whose node match $node
lsof -Ffci | awk -v node="$node" '
/^c/ { procname=substr($0, 2); }
/^f1$/ { getline; thisnode=substr($0, 2); }
/^p/ { if (procname != "" && thisnode == node) { print procname; procname=""; thisnode=""; } }
END { if (procname != ""&& thisnode == node) print procname; }
'
cat
Я использую эту функцию в своем .bash_aliases
, чтобы создать инструмент, похожий на тройник:
function teee {
#This can be used between pipes to print on screen what is coming in from the left command and flows to the next command
v="$(</dev/stdin)";
echo '---------------- pipe entry-------------' >/dev/tty;
while read -r l;do
echo "$l" >/dev/tty;
done <<<"$v";
echo '---------------- pipe exit-------------' >/dev/tty;
echo "$v"; ##echo to pipe buffer - necessary to keep the data flow to the next command
}
Тестирование:
cat file11
1
2
3
8
9
cat file11 |sed 's/3//' |teee |sed 's/1//'
---------------- pipe entry-------------
1
2
8
9
---------------- pipe exit-------------
2
8
9
В вашем случае вы можете заменить все >/dev/tty
на >logfile
внутри скрипта.
Вы можете сделать что-то вроде этого:
echo 'ls' | read var;echo $var > var_file;$var | myscript
Значение команды будет записано в файл var_file
.
echo 'ls'
даст ls
в качестве строкового ввода, а значение var
станет ls
. $var
расширится до ls
и передаст свой вывод через канал в myscript
.
Если у вас есть несколько команд и вы хотите получить их построчно в var_file
, замените >
на >>
, т.е.:
echo 'ls' | read var;echo $var >> var_file;$var | myscript
На самом деле у программы на принимающей стороне канала нет способа узнать, каков источник входящих данных. Используя ваш пример:
$ ls | myscript
Стандартный вывод ls
будет перенаправлен на стандартный ввод myscript
. Однако это будет совершенно неотличимо от:
$ ls > datafile
$ myscript < datafile
или
$ ls > datafile
$ cat datafile | myscript
или
$ wget -o - https://www.example.com/some/file/that/resembles/the/output/of/ls | myscript
или
$ ls | sed '/secrethiddenfile/d' | myscript
или даже
$ cat - | myscript
Текст — это просто текст.