One more awk can do the thing
awk -f tst.awk file | column -t | awk -v OFS='\t' '{ print $1,$2,$3,$4 }'
К сожалению, текущая версия стандартов POSIX sh не предлагает ни официального флага командной строки, ни переменной среды для надежного доступа к версии оболочки.
К счастью, есть обходные пути. Можно попробовать поставить --version
в оболочку для большинства производных bash (, кроме dash и posh ). Илиecho "$BASH_VERSION"
(баш ),echo "$ZSH_VERSION"
(зш ),echo "${.sh.version}"
(кш ).
Некоторые пакеты различают версии в имени двоичного файла, например, имя приложения командной строки Python v3 python3
. Возможно, имя текущего процесса оболочки включает в себя основную версию или двоичный путь оболочки, такой как /bin/sh
, ссылается на более конкретный путь, такой как /bin/bash4.4.12
. К сожалению, это соглашение не дошло до крошечного сообщества разработчиков оболочки, поэтому вряд ли эти проверки дадут полезные результаты.
Тем не менее, система упаковки может представить номер версии рассматриваемого пакета оболочки. Итак, запуститеdpkg -l <shell>
(производные Debian ),yum -l <shell>
(производные RHEL ),emerge -Opv <shell>
(Gentoo ),pacman -Qi dash
(Arch ),brew list dash
(Homebrew )и так далее. Если речь идет о оболочке sh
, то эта оболочка, скорее всего, предоставляется пакетом coreutils, поэтому запросите у диспетчера пакетов coreutils
, а не sh
.
Для родственных RVM, cygwin и других Unix-подобных -сред:каталог, содержащий оболочку, может называться версией оболочки. Поэтому возьмите абсолютный путь к приложению оболочки и посмотрите, появляется ли там имя.
Наконец, оболочка может быть просто предоставлена операционной системой, поэтому uname -a; cat /etc/*release*
может предоставляться хотя бы какой-то идентификатор для отслеживания версии оболочки.
Если все эти команды соединить точкой с запятой в скрипте, можно было бы получить достаточно всеобъемлющий инструмент грубой силы, похожий на nmap -, для определения версии данной оболочки.
Я действительно нашел способ. Модуль тестирования оболочки shunit2 , написанный как сценарии оболочки, имеет «библиотеку версий », в которой также есть код для определения используемой версии оболочки :
.VERSIONS_SHELLS="ash /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/sh /bin/zsh"
versions_shellVersion() {
shell_=$1
shell_present_=${FALSE}
case "${shell_}" in
ash)
[ -x '/bin/busybox' ] && shell_present_=${TRUE}
;;
*)
[ -x "${shell_}" ] && shell_present_=${TRUE}
;;
esac
if [ ${shell_present_} -eq ${FALSE} ]; then
echo 'not installed'
return ${FALSE}
fi
version_=''
case ${shell_} in
*/sh)
# TODO(kward): fix this
## this could be one of any number of shells. try until one fits.
#version_=`versions_shell_bash ${shell_}`
## dash cannot be self determined yet
#[ -z "${version_}" ] && version_=`versions_shell_ksh ${shell_}`
## pdksh is covered in versions_shell_ksh()
#[ -z "${version_}" ] && version_=`versions_shell_zsh ${shell_}`
;;
ash) version_=`versions_shell_ash ${shell_}` ;;
*/bash) version_=`versions_shell_bash ${shell_}` ;;
*/dash)
# simply assuming Ubuntu Linux until somebody comes up with a better
# test. the following test will return an empty string if dash is not
# installed.
version_=`versions_shell_dash`
;;
*/ksh) version_=`versions_shell_ksh ${shell_}` ;;
*/pdksh) version_=`versions_shell_pdksh ${shell_}` ;;
*/zsh) version_=`versions_shell_zsh ${shell_}` ;;
*) version_='invalid'
esac
echo ${version_:-unknown}
unset shell_ version_
}
# The ash shell is included in BusyBox.
versions_shell_ash() {
busybox --help |head -1 |sed 's/BusyBox v\([0-9.]*\).*/\1/'
}
versions_shell_bash() {
$1 --version 2>&1 |grep 'GNU bash' |sed 's/.*version \([^ ]*\).*/\1/'
}
versions_shell_dash() {
eval dpkg >/dev/null 2>&1
[ $? -eq 127 ] && return # return if dpkg not found
dpkg -l |grep ' dash ' |awk '{print $3}'
}
versions_shell_ksh() {
versions_shell_=$1
# try a few different ways to figure out the version
versions_version_=`${versions_shell_} --version : 2>&1`
if [ $? -eq 0 ]; then
versions_version_=`echo "${versions_version_}" \
|sed 's/.*\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/'`
else
versions_version_=''
fi
if [ -z "${versions_version_}" ]; then
_versions_have_strings
versions_version_=`strings ${versions_shell_} 2>&1 \
|grep Version \
|sed 's/^.*Version \(.*\)$/\1/;s/ s+ \$$//;s/ /-/g'`
fi
if [ -z "${versions_version_}" ]; then
versions_version_=`versions_shell_pdksh ${versions_shell_}`
fi
echo ${versions_version_}
unset versions_shell_ versions_version_
}
versions_shell_pdksh() {
_versions_have_strings
strings $1 2>&1 \
|grep 'PD KSH' \
|sed -e 's/.*PD KSH \(.*\)/\1/;s/ /-/g'
}
versions_shell_zsh() {
versions_shell_=$1
# try a few different ways to figure out the version
versions_version_=`echo 'echo ${ZSH_VERSION}' |${versions_shell_}`
if [ -z "${versions_version_}" ]; then
versions_version_=`${versions_shell_} --version 2>&1 |awk '{print $2}'`
fi
echo ${versions_version_}
unset versions_shell_ versions_version_
}
Это может даже сработать, чтобы получить версию оболочки, когда она не используется, но я признаю, что в моем случае просто использование $BASH_VERSION
или аналогичного может быть более эффективным.
Под лицензией Apache License @kward.