Рассмотреть jstack
. Не совсем достойный strace
, больше a pstack
- аналог, но по крайней мере даст Вам изображение снимка вовремя. Мог string'em вместе для получения сырой трассировки, если бы Вы имели к.
См. также предложения в этой статье SO: https://stackoverflow.com/questions/1025681/call-trace-in-java
Я сделал бы интенсивное использование из перенаправления ввода-вывода:
#!/bin/bash
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1
[[ $1 ]] && exec 3<$1 || exec 3<&0
[[ $2 ]] && exec 4>$2 || exec 4>&1
fgrep -v "stuff" <&3 >&4
Объяснение
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1
Тест, если входной файл был указан как параметр командной строки и если файл существует.
[[ $1 ]] && exec 3<$1 || exec 3<&0
Если $1
установлен, т.е. входной файл был указан, указанный файл открыт в дескрипторе файла 3
, иначе stdin
дублирован в дескрипторе файла 3
.
[[ $2 ]] && exec 4>$2 || exec 4>&1
Так же, если $2
установлен, т.е. выходной файл был указан, указанный файл открыт в дескрипторе файла 4
, иначе stdout
дублирован в дескрипторе файла 4
.
fgrep -v "stuff" <&3 >&4
Наконец fgrep
вызывается, перенаправляя stdin
и stdout
к ранее дескрипторам файлов набора 3
и 4
соответственно.
Повторное открытие стандартного ввода и вывода
Если Вы предпочли бы не открывать промежуточные дескрипторы файлов, альтернатива должна заменить соответствие дескрипторов файлов stdin
и stdout
непосредственно с указанными входными и выходными файлами:
#!/bin/bash
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1
[[ $1 ]] && exec 0<$1
[[ $2 ]] && exec 1>$2
fgrep -v "stuff"
Недостаток с этим подходом состоит в том, что Вы освобождаете способность дифференцировать вывод от самого сценария от вывода команды, которая является целью для перенаправления. В исходном подходе можно направить вывод сценария к неизмененному stdin
и stdout
, который в свою очередь, возможно, был перенаправлен вызывающей стороной сценария. К указанным входным и выходным файлам можно было все еще получить доступ через соответствующие дескрипторы файлов, которые отличны от сценария stdin
и stdout
.
Как насчет:
input="${1:-/dev/stdin}"
output="${2:-/dev/stdout}"
err="${3:-/dev/stderr}"
foobar <"$input" >"$output" 2>"$err"
Необходимо отметить это /dev/std(in|out|err)
не находятся в стандарте POSIX, таким образом, это будет только работать над системами, которые поддерживают эти специальные файлы.
Это также принимает нормальный вход: это не проверяет на существование файлов перед перенаправлением.
если Вы не возражаете против этого, вывод всегда перенаправляется к stdout, можно использовать следующую остроту:
cat $1 |fgrep -v "stuff" | tee
Можно использовать exec <foo
перенаправить вход сценария из файла foo
, и аналогично exec >foo
для вывода.
#!/bin/sh
set -e
if [ $# -ne 0 ]; then
exec <"$1"
shift
fi
if [ $# -ne 0 ]; then
exec >"$1"
shift
fi
fgrep -v "stuff"
Этот стиль является кратким, но не предоставляет себя хорошо подробному сообщению об ошибке.
Я не знаю, 'более ли это чисто', но здесь является некоторыми предложениями (это не тестируется код). Использование exec
(на Thomas Nyman), может привести к проблемам безопасности и должен рассматриваться с осторожностью.
Первое место повторяющийся код в функции.
# die <message>
function die(){
echo "Fatal error: $1, exiting ..." >&2
exit 1
}
# is_file <file-path>
function is_file(){
[[ -n "$1" && -f "$1" ]] && return 0
die 'file not found'
}
Здесь, вместо использования fgrep
, cat
Ваш друг. Затем используйте избранный случай:
case $# in
0) cat ;; # accepts stdin to stdout.
1) is_file "$1"; cat "$1" ;; # puts $1 to stdout.
2) is_file "$1"; cat "$1" > "$2" ;; # puts $1 to $2.
*) die 'too many arguments' ;;
esac
Другая альтернатива (который является чистым и очень компактным) должна загрузить инструкции в массиве и затем получить доступ к нему через значение $ #, что-то как указатель функции. Учитывая функцию is_file
выше, код Bash - что-то как:
# action array.
readonly do_stuff=(
'cat' # 0 arg.
'is_file \"$1\"; cat \"$1\"' # 1 arg.
'is_file \"$1\"; cat \"$1\" > \"$2\";' # 2 args.
)
# Main - just do:
[[ $# -le 2 ]] && ${do_stuff[$#]} || die 'too many arguments'
Я не 100% на синтаксисе, но двойных кавычек нужно оставить. Лучше всего к переменным двойной кавычки, которые содержат пути к файлам.
Добавленное примечание, при записи в $2 - должно, вероятно, проверить, что файл не существует, или это будет перезаписано.
stdin
иstdout
. Лично, я был бы обычно тихий предпочитать исходный подход по причинам, объясненным в обновленном ответе. – Thomas Nyman 09.10.2013, 19:29