2016-08-10 3 views
0

У меня есть следующий короткий Баш скрипт:Почему вывод этого сценария bash различен при каждом запуске?

#!/bin/bash 
cp /dev/null out.sh 
while IFS=' ' read -r b c d e 
do 
    echo -ne "sendevent " >> out.sh 
    echo -ne "/dev/input/event1 " >> out.sh 
    echo -ne "$((0x$c)) " >> out.sh 
    echo -ne "$((0x$d)) " >> out.sh 
    echo -ne "$((0x$e)) " >> out.sh 
    echo >> out.sh 
done < "in.sh" 

Он принимает команда считывает из другого сценария под названием in.sh в виде /dev/input/event1: 0003 0039 0000006d, и мне нужно для вывода на другой сценарий под названием out.sh в виде sendevent /dev/input/event1 3 57 109, где он преобразует последние три слагаемых из шестнадцатеричного в десятичный.

Однако, когда я запускаю скрипт, я получаю квази-сломанный вывод, который изменяется каждый раз, когда я его запускаю. Правильный вывод должен быть вдоль линий:

sendevent /dev/input/event1 3 57 109 
sendevent /dev/input/event1 3 53 40 
sendevent /dev/input/event1 3 54 620 
#and so on 

Вот фотография моего фактического выхода:

out.sh screenshot

Каждый раз, когда я бегу сценарий, выход не немного отличается, и никогда не равномерная как я хочу. Почему он выводится по-разному каждый раз? Как исправить это, чтобы он выводился в том виде, в котором я хочу?

Я попытался добавить в sleep .01 после последнего заявления echo, и это не исправило проблему.

EDIT: В соответствии с просьбой, вот фрагмент из моей in.sh:

/dev/input/event1: 0003 0039 0000006d 
/dev/input/event1: 0003 0035 00000028 
/dev/input/event1: 0003 0036 0000026c 
/dev/input/event1: 0001 014a 00000001 
/dev/input/event1: 0000 0000 00000000 
/dev/input/event1: 0003 0039 ffffffff 
/dev/input/event1: 0001 014a 00000000 
/dev/input/event1: 0000 0000 00000000 
/dev/input/event1: 0003 0039 0000006e 
/dev/input/event1: 0003 0035 0000020f 
/dev/input/event1: 0003 0036 000003dd 
/dev/input/event1: 0001 014a 00000001 
/dev/input/event1: 0000 0000 00000000 
/dev/input/event1: 0003 0039 ffffffff 
/dev/input/event1: 0001 014a 00000000 
/dev/input/event1: 0000 0000 00000000 
/dev/input/event1: 0003 0039 0000006f 
/dev/input/event1: 0003 0035 000001b6 
/dev/input/event1: 0003 0036 00000076 
/dev/input/event1: 0001 014a 00000001 
/dev/input/event1: 0000 0000 00000000 
/dev/input/event1: 0003 0039 ffffffff 

И вот два разных выходов, которыми управляют один за другим, с тем же in.sh:

sendevent /dev/input/event1 3 109 
sendevent /dev/input/event1 3 54 620 
sendevent /dev/input/event1 1 330 1 
sendevent /dev/input/event1 0 0 0 
sendevent /dev/input/event1 3 57 4294967295 
/dev/input/event1 1 330 0 
sendevent /dev/input/event1 0 0 
sendevent /dev/input/event1 3 57 110 
3 53 527 
sendevent /dev/inp3 54 989 
/dev/input/event1 1 330 1 
sendevent 3 57 4294967295 
sendevent /dev/input/event1 /event1 1 330 0 
sendevent /dev/input/event1 0 0 0 
sendevent /dev/input/event1 57 111 
sendevent /dev/input/event1 3 53 438 sendevent /dev/input/event1 3 54 
sendevent /dev/input/event1 1 1 
sendevent 
sendevent /dev/input/event1 57 4294967295 
/dev/input/event1 1 330 /dev/input/event1 0 0 0 
sendevent /dev/input/event1 3 57 112 
sendevent /dev/input/event1 3 53 
sendevent /dev/input/event1 3 54 881 
sendevent /dev/input/event1 
sendevent /dev/input/event1 3 57 t1 0 0 0 4294967295 
sendevent 1 330 0 
sendevent/dev/input/event1 0 0 0 
113 
sendevent /dev/input/event1 3 53 
sendevent /dev/input/event1 54 901 
/dev/input/event1 1 330 1 
/dev/input/event1 0 0 0 sendevent /dev/input/event1 3 57 4294967295 
330 0 

И второй выход:

sendevent /dev/input/event1 3 57 109 
sendevent /dev/input/event1 3 53 620 
sendevent /dev/input/event1 54 1 330 1 /dev/input/event1 0 0 0 sendevent /dev/input/event1 3 57 
sendevent /dev/input/event1 1 330 
sendevent /dev/input/event1 0 0 0 
sendevent /dev/input/event1 3 57 110 
/dev/input/event1 3 53 
sendevent /dev/input/event1 54 989 
/dev/input/event1 1 330 
sendevent /dev/input/event1 0 0 
sendevent 3 57 4294967295 
sendevent /dev/input/event1 1 0 
sendevent 0 0 0 
put/event1 sendevent /dev/input/event1 3 111 
sendevent 3 53 438 
/event1 sendevent /dev/input/event1 3 54 
sendevent /dev/input/event1 330 1 
0 0 0 
nt /dev/input/event1 sendevent /dev/input/event1 3 4294967295 
sendevent 0 
sendevent /dev/input/event1 0 0 0 
sendevent /dev/input/event1 3 57 112 
sendevent /dev/input/event1 3 53 247 
sendevent /dev/input/event1 3 54 881 sendevent /dev/input/event1 1 330 1 
/dev/input/event1 0 0 
sendevent /dev/input/event1 57 4294967295 
sendevent /dev/input/event1 1 330 
sendevent /dev/input/event1 0 0 0 
sendevent 3 57 113 
sendevent 3 53 246 
/event1 sendevent /dev/input/event1 3 54 
sendevent /dev/input/event1 330 1 
/dev/input/event1 0 0 0 
/dev/input/event1 3 57 4294967295 sendevent /dev/input/event1 1 330 
sendevent /dev/input/event1 0 0 
sendevent 3 57 114 
/event1 sendevent /dev/input/event1 3 53 
sendevent /dev/input/event1 3 54 882 sendevent /dev/input/event1 1 1 
sendevent /dev/input/event1 0 0 0 sendevent /dev/input/event1 3 sendevent /dev/input/event1 1 0 
sendevent 0 0 0 
+1

FYI, указанная POSIX альтернатива 'echo -ne' -' printf '% b''. –

+0

Вы пытаетесь прочитать * script * 'in.sh' или вывод из' in.sh'? Поскольку ваш скрипт в настоящее время читает содержимое файлов сценариев. –

+1

...что вы не должны ** генерировать генерации кода посредством конкатенации строк, не используя собственные возможности экранирования оболочки (например, 'printf '% q''); вниз, этот путь - уязвимости оболочки. –

ответ

2

Ниже использует первоначальный grep проход, чтобы дезинфицировать вход, избегая потенциальных атак инъекций оболочки:

#!/bin/sh 
grep '^[^ ]\+ [0-9a-f ]\+$' <in.sh | while IFS=' ' read -r _ c d e; do 
    printf 'sendevent /dev/input/event1 %d %d %d\n' \ 
    "$((0x$c))" "$((0x$d))" "$((0x$e))" 
done >out.sh 

Примечание:

  • out.sh только открыт один раз, а не возобновлено перед каждым команду, которая хочет писать к ней, и закрывается после окончания этой индивидуальной команды (как это происходит с оператором >> при каждой записи).
  • Использование printf один раз в строке гарантирует, что каждая запись будет выполняться как атомный syscall (когда используются достаточно короткие линии, как это будет справедливо здесь), а также избегает в зависимости от поведения, которое the POSIX specification for echo explicitly declines to specify; вывод echo -n явно не определен стандартом, тогда как обработка -e в качестве опции, а не аргумента, фактически противоречит букве стандарта (и поведение по умолчанию Баша по этому вопросу может быть отключено, как и в комбинации set -o posix и shopt -s xpg_echo) ,
+0

Вау, я пытался дать вам пример 'in.sh' и' out.sh', но ваш ответ уже исправил мою проблему. Хотели бы вы, чтобы я предоставил другие примеры кода для будущей ссылки? Спасибо за быстрый ответ. –

+1

Если вы можете добиться чего-то, чтобы иметь подходящий автономный репродуцир, который другие люди могут запустить, чтобы увидеть проблему самостоятельно, это принесло бы много пользы с точки зрения того, чтобы помочь вопросу быть полезным другим людям - так что если вы не против идти в ногу с этими усилиями, пожалуйста, сделайте это! –

Смежные вопросы