резюме: Почему это не удается
$ ssh foo 'R --version | head -n 1'
bash: R: command not found
но это удается
$ ssh foo 'grep -nHe 'bashrc' ~/.bash_profile'
/home/me/.bash_profile:3:# source the users .bashrc if it exists
/home/me/.bash_profile:4:if [ -f "${HOME}/.bashrc" ] ; then
/home/me/.bash_profile:5: source "${HOME}/.bashrc"
$ ssh foo 'grep -nHe "\WR\W" ~/.bashrc'
/home/me/.bashrc:118:alias R='/share/linux86_64/bin/R'
$ ssh foo '/share/linux86_64/bin/R --version | head -n 1'
R version 2.14.1 (2011-12-22)
? подробности:
Я (без root) пользователь на 2 кластерах. Один использует модули среды, поэтому любой сервер в этом кластере может предоставить (через module add
) практически те же ресурсы. Другой кластер, с которым я, к сожалению, тоже должен работать, имеет серверы, управляемые индивидуально, поэтому я имею привычку делать, например,
EXEC_NAME='whatever'
for S in 'foo' 'bar' 'baz' ; do
ssh ${SERVER} "${EXEC_NAME} --version"
done
Это отлично работает для пакетов, установленных нормально / последовательно, но часто (по неизвестным мне причинам) пакеты не работают: например, (сравните псевдоним ниже с псевдонимом выше),
$ ssh bar 'R --version | head -n 1'
bash: R: command not found
$ ssh bar 'grep -nHe 'bashrc' ~/.bash_profile'
/home/me/.bash_profile:3:# source the users .bashrc if it exists
/home/me/.bash_profile:4:if [ -f "${HOME}/.bashrc" ] ; then
/home/me/.bash_profile:5: source "${HOME}/.bashrc"
$ ssh bar 'grep -nHe "\WR\W" ~/.bashrc'
/home/me/.bashrc:118:alias R='/share/linux/bin/R'
$ ssh bar '/share/linux86_64/bin/R --version | head -n 1'
R version 2.14.1 (2011-12-22)
Использование псевдонимов хорошо справляется с этими различиями в установке, когда я в интерактивном режиме подключаюсь к серверу, но терпит неудачу, когда я пытаюсь создать сценарии команд ssh (как указано выше); т.е.
# interactively
$ ssh foo
...
foo> R --version
называет мой псевдоним для R
на удаленном хосте =foo
, но
# scripting
$ ssh foo 'R --version'
нет. Что мне нужно сделать, чтобы сделать ssh foo "<command/>"
загрузить мои псевдонимы на удаленный хост?
Из bash
страница руководства:
Псевдонимы не раскрываются, если оболочка не интерактивна, если только опция оболочки expand_aliases не установлена с помощью shopt (см. Описание shopt в разделе «ВСТРОЕННЫЕ КОМАНДЫ ОБОЛОЧКИ» ниже).
Тебе надо shopt -s expand_aliases
в вашем пульте .bashrc
s, и убедитесь, что те .bashrc
обрабатываются в неинтерактивном режиме; по умолчанию .bashrc
для вашего дистрибутива может включать проверку досрочного прекращения в неинтерактивном режиме, например Ubuntu использует:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
Ответ Эндрю объяснил причину. Приведу только одно решение:
Вместо того, чтобы использовать aliases
, используйте их function equivalents
.
Например:
Вместо того, чтобы использовать: alias ll='ls -lah'
Использовать это:
function ll{
ls -lah "$@"
}