Я предлагаю, чтобы Вы изменили дом пользователя для указания на целевой каталог. Можно сделать это путем редактирования /etc/passwd
непосредственно или usermod --home NEW_HOME_DIR username
(это также скопирует файлы с предыдущего).
Обновление: Что касается блокировки, нет многих вариантов кроме a chroot
тюрьма. Если Вы устанавливаете оболочку входа в систему на /bin/rbash
, это запустит ограниченную оболочку. Среди прочего это означает cd
не будет работать, ни будут команды то использование полные пути. Читайте bash(1)
страница справочника под RESTRICTED SHELL
для получения дальнейшей информации.
Можно отметить функцию как 'только для чтения' в file2.sh.
Примечание: это вызовет предупреждения, когда file1.sh более поздние попытки определить (переопределят) функцию.
Те предупреждения появятся на stderr и могли доставить неприятности. Я не знаю, могут ли они быть отключены.
Дальнейшее примечание: это МОГЛО БЫ заставить сценарии перестать работать, если они проверяют статус возврата функционального определения. Я думаю, что существует также опция удара, которая может быть установлена, который заставил бы ненулевой статус возврата где угодно прерывать выполнение сценария.Удачи!
Можно ли изменить file1.sh? Просто использование условных выражений, чтобы проверить, определяется ли функция прежде, чем определить его, было бы большим надежным решением.
Вот пример использования 'только для чтения'.
hobbes@metalbaby:~/scratch$ mkdir bash-source-test
hobbes@metalbaby:~/scratch$ cd bash-source-test
hobbes@metalbaby:~/scratch/bash-source-test$ cat > file2.sh
#!/bin/bash
fname(){
echo "file2"
}
readonly -f fname
hobbes@metalbaby:~/scratch/bash-source-test$ cat > file1.sh
#!/bin/bash
fname(){
echo "file1"
}
readonly -f fname
hobbes@metalbaby:~/scratch/bash-source-test$ cat >top.sh
#!/bin/bash
if [ $1 ]; then
source file2.sh
fi
source file1.sh
fname
hobbes@metalbaby:~/scratch/bash-source-test$ chmod +x *.sh
hobbes@metalbaby:~/scratch/bash-source-test$ ./top.sh
file1
hobbes@metalbaby:~/scratch/bash-source-test$ ./top.sh hello
file1.sh: line 4: fname: readonly function
file2
hobbes@metalbaby:~/scratch/bash-source-test$
Если те сценарии действительно интерпретируются bash
(а не в sh
режим эмуляции), и если file1.sh
определяет, но не использует foo
, Вы могли переопределить source
и .
команды таким способом это после определения источника file1.sh
, это удостоверяется file1.sh
не переопределяет foo
, например, путем искажения его далеко к чему-то еще:
$ cat file1.sh
foo() { echo original foo; }
$ cat file2.sh
foo() { echo new foo; }
$ cat main.sh
file2_sourced=false
source() {
case ${1##*/} in
(file2.sh)
file2_sourced=true;;
(file1.sh)
if "$file2_sourced"; then
alias foo=original_foo
builtin source "$@"; local "ret=$?"
unalias foo
return "$ret"
fi;;
esac
builtin source "$@"
}
.() { source "$@"; }
source file2.sh
source file1.sh
foo
original_foo
$ bash main.sh
new foo
original foo
Или возможно более соответствующий:
source() {
shopt -s expand_aliases
if [ "${1##*/}" = file1.sh ] && command -v foo > /dev/null 2>&1; then
# foo already defined, make file1.sh define original_foo this time
alias foo=original_foo
builtin source "$@"; local "ret=$?"
unalias foo
return "$ret"
else
builtin source "$@"
fi
}
Это: только предотвратите file1.sh
от переопределения foo
.
Теперь, если те другие сценарии это main.sh
вызовы выполняются в противоположность тому, чтобы быть полученным, необходимо было бы экспортировать их source
и .
функции в main.sh
:
export -f source .
На самом деле также возможно сделать это без изменения main.sh
, путем вызова его как:
env BASHOPTS=expand_aliases source='() {
if [ "${1##*/}" = file1.sh ] && command -v foo > /dev/null 2>&1; then
# foo already defined, make file1.sh define original_foo this time
alias foo=original_foo
builtin source "$@"; local "ret=$?"
unalias foo
return "$ret"
else
builtin source "$@"
fi
}' .='() { source "$@"; }' bash main.sh
file1.sh
и file2.sh
были получены и они могли быть получены несколько время из сценариев, которые он не мог изменить (почему мы не знаем).
– Stéphane Chazelas
03.08.2013, 20:13
Я ничего никогда не писал кроме маленьких сценариев удара для основного системного администратора и задач автоматизации, таким образом, у меня есть очень мало опыта с определением источника функций из других файлов. Это может поэтому быть очень наивно или не портативно или что-то, но, по крайней мере, в моей системе, и на большинстве языков программирования я знаю, если Вы переопределяете что-то, что это остается переопределенным.
Другими словами, пока Вы удостоверяетесь Вы источник file1.sh
прежде file2.sh
и экспортируйте функцию впоследствии, необходимо всегда экспортировать функцию из file2.sh
если это было загружено и из file1.sh
если это не имеет:
$ cat file1.sh
#!/bin/bash
fname(){
echo "BBBBB"
}
$ cat file2.sh
#!/bin/bash
fname(){
echo "CCCCC"
}
$ cat foobar.sh
#!/bin/bash
source file1.sh
if [ $1 ]; then
source file2.sh;
fi
export -f fname;
./run_function.sh
$ cat run_function.sh
#!/bin/bash
fname
Любые сценарии называют (например, ./run_function.sh
) будет иметь какой бы ни fname
был определен в последний раз, таким образом, они загрузят тот из file2.sh
если это было получено и от file.sh
если это не имеет:
$ ./foobar.sh
BBBBB
$ ./foobar.sh hello
CCCCC
Я думаю, что, вероятно, самый простой ответ здесь - получить функцию из этих файлов сценариев.
#file[12]
#foo() { : removed; }
. ./foo.fn
#and rest of script
#foo.fn
foo() { : old version is always defined; }
[ -z "${NEWFOO:+1}" ] ||
foo() { : new version defined only if $NEWFOO; }
#your caller script
export NEWFOO=1
case $srcarg in (./file1) unset NEWFOO;; esac
#or however ^that part^ is usually done
. "$srcarg"
#and rest of script