Что эквивалентно xargs -r под OsX - PullRequest
7 голосов
/ 10 января 2012

В OSX они эквивалентны xargs -r в Linux? Я пытаюсь найти способ прервать канал, если нет данных.

Например, представьте, что вы делаете следующее:

touch test
cat test | xargs -r echo "content: "

Это не дает никакого результата, потому что xargs прерывает канал.

Есть ли какая-либо опция hidden xargs или что-то еще для достижения того же результата в OSX?

Ответы [ 5 ]

2 голосов
/ 10 января 2012

Стандарт POSIX для xargs требует, чтобы команда была выполнена один раз, даже если аргументов нет.Это неприятность, поэтому GNU xargs имеет опцию -r.К сожалению, ни BSD (MacOS X), ни другие основные версии Unix (AIX, HP-UX, Solaris) не поддерживают его.

Если это важно для вас, приобретите и установите GNU xargs где-то в вашей среденайдет его, не затрагивая систему (поэтому не заменяйте /usr/bin/xargs, если вы не смелый человек, чем я - но /usr/local/bin/xargs может быть в порядке, или $HOME/bin/xargs, или ...).

2 голосов
/ 02 декабря 2013

Не существует стандартного способа определить, является ли запущенный вами xargs GNU или нет. Я устанавливаю $gnuargs в «true» или «false», а затем имею функцию, которая заменяет xargs и делает правильные вещи.

В Linux, FreeBSD и MacOS этот скрипт работает для меня. Стандарт POSIX для xargs требует, чтобы команда выполнялась один раз, даже если аргументов нет. FreeBSD и MacOS X нарушают это правило, поэтому не нуждаются в «-r». GNU находит это раздражающим и добавляет -r. Этот скрипт работает правильно и может быть улучшен, если вы найдете версию Unix, которая делает это другим способом.

#!/bin/bash

gnuxargs=$(xargs --version 2>&1 |grep -s GNU >/dev/null && echo true || echo false)

function portable_xargs_r() {
  if $gnuxargs ; then
    cat - | xargs -r """$@"""
  else
    cat - | xargs """$@"""
  fi
}

echo 'this' > foo
echo '=== Expect one line'
cat foo | portable_xargs_r echo "content: "
echo '=== DONE.'

cat </dev/null > foo
echo '=== Expect zero lines'
cat foo | portable_xargs_r echo "content: "
echo '=== DONE.'
2 голосов
/ 10 января 2012

Вы можете использовать test или [:

if [ -s test ] ; then cat test | xargs echo content: ; fi
0 голосов
/ 26 октября 2017

Вот быстрый и грязный xargs-r с использованием временного файла.

#!/bin/sh
t=$(mktemp -t xargsrXXXXXXXXX) || exit
trap 'rm -f $t' EXIT HUP INT TERM
cat >"$t"
test -s "$t" || exit
exec xargs "$@" <"$t"
0 голосов
/ 02 декабря 2013

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

...