Bash test wc с '-ge' - ошибка деления на 0

У меня это сработало, когда я попробовал это с файлом mp3.

$ ffmpeg -i somefile.mp3 -f segment -segment_time 3 -c copy out%03d.mp3

Где -segment_time - это количество времени, которое вы хотите для каждого файла (в секундах).

Ссылки

3
12.02.2017, 03:25
2 ответа

Это из-за вывода wc -l / filename , это будет вывод, например:

5 /filename

, но вы выполняете целочисленное сравнение (оператор: -ge ), следовательно, посторонняя часть / filename недопустима, что приводит к сообщению об ошибке.

Просто передайте имя файла в wc через STDIN, чтобы wc просто возвращал счетчик:

[[ $(wc -l </disk1/environment.sh) -ge 0 ]]

Во втором случае [[$ (wc -l / disk1 / environment.sh)> 0]] , вы просто проверяете, сортируется ли вывод подстановки команды, $ (wc -l /disk1/environment.sh) после 0 , лексикографически; что всегда будет иметь место, если wc не вернет некоторую ошибку и ничего не выдаст на STDOUT.

Обратите внимание: [ не поддерживает арифметические операторы, такие как > , > = , <, < = , вам понадобится ключевое слово (( для них:

(( $(wc -l </disk1/environment.sh) > 0 ))
10
27.01.2020, 21:11

Вторая попытка не вызывает ошибки, но это не так. не работает нормально, если вы пытаетесь проверить, содержит ли файл хотя бы одну строку.

Вывод команды wc -l "/disk1/environment.sh" состоит из количества строк в файле, пробела и имени файла. Если вы хотите использовать количество строк, вам нужно его извлечь. Вместо разделения вывода существует более простой способ: вместо передачи имени файла в командной строке перенаправить вывод wc из файла. Затем wc печатает только номер без имени файла.

if [[ $(wc -l <"/disk1/environment.sh") -ge 0 ]];then  
   echo "File has data"  
fi

Или, поскольку вы все равно используете синтаксис bash,

if (($(wc -l <"/disk1/environment.sh") >= 0)); then  
   echo "File has data"  
fi

Конечно, это всегда верно, поскольку количество строк всегда больше или равно 0. Но вы можете получить полезные результаты с другими числами.

В первой попытке вы используете оператор -ge . Это оператор над целыми числами. Вы получаете сообщение об ошибке, потому что левая часть не целое число, а что-то вроде 42 /disk1/environment.sh.

Во второй попытке вы используете оператор < в условном операторе. Это оператор сравнения строк (в лексическом порядке). Так получилось, что вывод wc -l /disk1/environment.sh всегда лексически упорядочен после 0 , так как он начинается с цифры, поэтому [[$ ( wc -l <"/ disk1 / environment.sh")> 0]] всегда верно. Исключение составляют случаи, когда /disk1/environment.sh не существует; в этом случае wc -l ничего не выводит на стандартный вывод (вместо этого записывает сообщение об ошибке в стандартную ошибку), и сравнение неверно.

Сравнение количества строк в файле с 0 не очень полезно. В современных системах wc -l подсчитывает количество символов новой строки. В текстовом файле количество символов новой строки равно 0, только если файл пуст. (Обычно wc -l возвращает 0, если файл не содержит символа новой строки; текстовый файл содержит новую строку в конце каждой строки, а количество новых строк в нетекстовых файлах редко полезная информация.) В условных выражениях есть оператор, проверяющий, пуст ли файл, вам не нужно вызывать wc .

if [[ ! -e /disk1/environment.sh ]]; then
  if [[ -L /disk1/environment.sh ]]; then
    echo "/disk1/environment.sh is a broken symbolic link"
  else
    echo "/disk1/environment.sh does not exist"
  fi
elif [[ ! -r /disk1/environment.sh ]]; then
  echo "/disk1/environment.sh exists but is not readable"
elif [[ ! -s /disk1/environment.sh ]]; then
  echo "/disk1/environment.sh is empty or is a special file (name pipe, etc.)"
else
  echo "/disk1/environment.sh is not empty"
fi
0
27.01.2020, 21:11

Теги

Похожие вопросы