Проведите ввод через tr
и замените все дефисы символами подчеркивания, которые используются для распознавания отрицательного числа с помощьюdc
:
$ tr \- _ < inp.txt |
dc -e '
[q]sq
[lN1+sN]sa
[5>az0<b]sb
[?z0=q0sNlbxlNpcz0=c]sc
lcx
'
Я почистил код для вас:
#!/bin/bash
#check if the user put a file name
if [ $# -gt 0 ]; then
#check if the file is exist in the current directory
if [ -f "$1" ]; then
#check if the file is readable in the current directory
if [ -r "$1" ]; then
echo "File:$1"
echo "$(wc -c <"$1")"
comp=$(bzip2 -k $1)
echo "$(wc -c <"$comp")"
else
echo "$1 is unreadable"
exit
fi
else
echo "$1 is not exist"
exit
fi
fi
Обратите внимание на дополнительный fi
в предпоследней строке.
Строка 11 не имеет особого смысла, так как bzip2 -k test.file
не создает никакого вывода. Следовательно, переменная comp
просто пуста.
Простой подход состоит в том, чтобы просто знать, что расширение будет .bz2
, так что вы можете сделать, например,:
echo "$(wc -c <"${1}.bz2")"
и вообще не использовать переменную comp
.
bzip2 -k
ничего не выводит, поэтому запуск его в подстановке команд и запись вывода в переменную comp
оставит эту переменную пустой. Эта пустая переменная - ваша главная проблема. Также лучше, как в более эффективном, использовать stat
, чем wc -c
, чтобы получить размер файла в stat
, просто прочитает размер файла из метаданных файла, не утруждая себя чтением всех данных из файла.
Вы также выполняете множество ненужных проверок существования и читабельности файла, что отвлекает от сценария. Это проверки, которые bzip2
выполняет в любом случае, и вы можете использовать этот факт, чтобы не проверять большую часть этого самостоятельно.
Предложение:
#!/bin/sh
pathname=$1
if ! bzip2 -k "$pathname"; then
printf 'There were issues compressing "%s"\n' "$pathname"
echo 'See errors from bzip2 above'
exit 1
fi >&2
size=$( stat -c %s "$pathname" )
csize=$( stat -c %s "$pathname.bz2" )
printf '"%s"\t%s --> %s\n' "$pathname" "$size" "$csize"
Этот сценарий использует статус выхода bzip2
, чтобы определить, успешно ли прошло сжатие файла. В случае сбоя он выводит диагностическое сообщение в дополнение к диагностическому сообщению, которое bzip2
уже должно было быть выдано на терминале.
Поскольку вы используете -k
с bzip2
, чтобы сохранить несжатый файл,размеры обоих файлов можно получить после оператора if
. Если бы вы удалили -k
из команды, вам, естественно, пришлось бы получить размер несжатого файла перед оператором if
.
Способ использования stat
в сценарии предполагает, что сценарий работает в системе Linux. Утилита stat
не является стандартной -и реализована с другими опциями в других системах. Например, в macOS или OpenBSD вам придется использовать stat -f %z
вместо stat -c %s
.
Тестирование:
$./script
bzip2: Can't open input file : No such file or directory.
There were issues compressing ""
See errors from bzip2 above
$./script nonexisting
bzip2: Can't open input file nonexisting: No such file or directory.
There were issues compressing "nonexisting"
See errors from bzip2 above
$./script file
"file" 600 --> 43
$./script file
bzip2: Output file file.bz2 already exists.
There were issues compressing "file"
See errors from bzip2 above
$ rm -f file.bz2
$ chmod u-r file
$./script file
bzip2: Can't open input file file: Permission denied.
There were issues compressing "file"
See errors from bzip2 above