Bash, название stdin файла?

Необходимо будет установить сервер X-окон на поле окон. Я рекомендую http://sourceforge.net/projects/xming/ XMing.

На Вашем поле Linux включите X11Forwarding в/etc/ssh/sshd_config

При соединении с сервером от Шпаклевки нажмите на Connection> SSH> X11> Tick X11 Forwarding

После того как Вы вошли в систему, можно протестировать, если это работает путем выполнения

$ echo $DISPLAY

Вывод должен быть похожим на это

localhost:11.0

Затем попробуйте, запускает приложение GUI

$ xclock

4
28.09.2013, 14:42
3 ответа

Смысл stdin это, это может быть что-либо, это может, например, быть канал, сеть снабжают сокетом регулярный файл, устройство, это может быть половина пути через регулярный файл, когда Ваш сценарий запускается... Если Вы не можете обработать данные в одной передаче, то Вы ограничиваете себя seekable файлами, которые являются регулярными файлами и несколькими файлами устройств, или должны будут хранить информацию так или иначе (во временном файле или памяти...). Возможно здесь получить всю информацию сразу все же.

Например, Вы могли сделать:

$ grep -o '[<>]' < a.html | sort | uniq -c
     82 <
     82 >

POSIXly:

fold -w 1 a.html | grep '[<>]' | sort | uniq -c

Обнаружить несоответствие:

if fold -w 1 a.html | awk '{n[$0]++}
     END{exit(n["<"]!=n[">"])}'
then
  echo match
else
  echo mismatch
fi

Теперь, для ответа на вопрос в предмете, на Linux, можно найти "название" stdin с:

readlink -f /dev/stdin

Пример:

$ readlink -f /dev/stdin < a
/home/chazelas/a
$ : | readlink -f /dev/stdin
/proc/20238/fd/pipe:[758683]

(20238 выше pid readlink, так, чтобы путь не имел большого применения после readlink вышел, и это не было бы так или иначе, это pipe:[758683] является просто информационным, это не может быть открыто).

И в более общем плане если lsof доступно:

lsof -ad0 -p "$$" -Fn 2> /dev/null | sed -n 'n;s/^n//p'

(Хотя, $$ будучи pid процесса, который выполнил оболочку, она не будет работать в подоболочках, которым перенаправили их stdin),

Теперь, Вы не обязательно сможете вновь открыть тот файл для чтения, и даже когда Вы делаете, читение из того файла не могло бы дать Вам те же данные снова (думайте о каналах, например).

$ seq 3 > a
$ { cat; cat /dev/stdin; } < a
1
2
3
1
2
3
$ cat a | { cat; cat /dev/stdin; }
1
2
3

На Linux, открываясь /dev/stdin если stdin будет регулярным файлом, то считает файл из запуска снова, в то время как в других системах, открываясь/dev/stdin больше похож на a dup(0), это - это, не перематывает файл к началу (на первом примере выше, это произвело бы 1\n2\n3\n однажды вместо дважды).

15
27.01.2020, 20:44

Необходимо будет сохранить содержание файла так или иначе. Можно использовать переменную.

content=`cat`
x=`echo "$content" | grep -o '>' | wc -l`
y=`echo "$content" | grep -o '<' | wc -l`
if [ "$x" -ne "$y" ]; then
  echo "Mismatch!"
fi
echo $x
echo $y

Или временный файл (необходимый, если example.html содержит пустые байты).

tmp=`mktemp`
trap "rm $tmp" EXIT
x=`grep -o '>' "$tmp" | wc -l`
y=`grep -o '<' "$tmp" | wc -l`
if [ "$x" -ne "$y" ]; then
  echo "Mismatch!"
fi
echo $x
echo $y

Если чтение содержания файла от stdin не является требованием, можно передать имя файла как аргумент сценарию.

x=`grep -o '>' "$1" | wc -l`
y=`grep -o '<' "$1" | wc -l`
if [ "$x" -ne "$y" ]; then
  echo "Mismatch!"
fi
echo $x
echo $y

Назовите сценарий как так:

$ ./myscript.sh example.html
7
27.01.2020, 20:44
  • 1
    +1, потому что это отвечает на общий вопрос того, как симулировать stdin, является файлом, и не пытающийся конкретно считать скобки. Это также в основном поражает все 3 способа сделать, это (сохраните stdin к переменной, сохраните stdin в файл, не используйте stdin). –  Mark Lakata 29.09.2013, 08:30

Одна возможность для Вашей задачи:

#!/bin/bash

if [[ -n $1 ]]; then
   if [[ ! -f $1 ]] || [[ ! -r $1 ]]; then
      echo >&2 "File \`$1' not found or not readable."
      exit 1
   fi
   exec "$0" < "$1"
fi

declare -A hary
while read c; do
   (( ++hary[$c] ))
done < <(grep -o '[<>]')

echo "> ${hary[>]}"
echo "< ${hary[<]}"

При вызове этого сценария countmismatched (можно выбрать более короткое имя), Вы сможете использовать его с или без имени файла. Несколько возможностей:

$ countmismatched example.html
$ countmismatched < example.html
$ cat example.html | countmismatched

Вывод будет чем-то как:

> 41
< 42

Если необходимо обнаружить не соответствовавший, добавьте в конце сценария:

if (( hary[<]} != hary[>] )); then
    echo "Mismatched brackets"
else
    echo "It's all good"
fi

или что-то более явное:

((difference=hary[<]-hary[>]))
if (( difference>0 )); then
    echo "Mismatched brackets: you have $difference more <'s than >'s"
elif (( difference<0 )); then
    echo "Mismatched brackets: you have $((-difference)) more >'s than <'s"
else
    echo "It's all good"
fi
1
27.01.2020, 20:44

Теги

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