В сценарии Cat in expect добавлена ​​новая строка до конца строки

У меня есть следующий сценарий expect

 spawn cat version expect -re 5.*.* set VERSION $expect_out(0,string) spawn rpm --addsign dist/foo-$VERSION-1.i686.rpm 

Команда cat получает версию правильно, но, похоже, добавляет новую строку. Поскольку я ожидаю, что результат будет следующим:

dist/foo-5.xx-1.i686.rpm

но я получаю в том числе ошибку в начале следующего:

 cannot access file dist/foo-5.xx -1.i686.rpm 

Почему expect добавление новой строки в вывод команды cat и есть ли способ сделать это не выполненным или исправить выход команды cat?

TCL может читать файл напрямую без осложнения spawn cat :

 #!/usr/bin/env expect # open a (read) filehandle to the "version" file... (will blow up if the file # is not found) set fh [open version] # and this call handily discards the newline for us, and since we only need # a single line, the first line, we're done. set VERSION [gets $fh] # sanity check value read before blindly using it... if {![regexp {^5\.[0-9]+\.[0-9]+$} $VERSION]} { error "version does not match 5.xy" } puts "spawn rpm --addsign dist/foo-$VERSION-1.i686.rpm" 

Скорее всего, у вас есть символ новой строки в конце вашего файла version , поэтому expect не столько добавления новой строки, сколько слепо делать то, что вы сказали. IMHO, было бы легче настроить сценарий ожидания, чтобы вычеркнуть любые новые строки до появления команды rpm , и это гарантирует, что вы снова не столкнетесь с этой проблемой, если другое редактирование вернет завершающую новую строку даже после того, как вы удалили Это.

Даже если у вас нет завершающей строки в файле version , я все равно советую вам добавить вызов strip() (конечно, для правильного синтаксиса для expect ), чтобы справиться с этой ситуацией.

Как говорит ТРИГ, вы должны прочитать файл напрямую. Кроме того, используя cat , как говорит Джон, в конце файла будет новая строка, и это станет \r\n (возврат каретки, новая строка) при прохождении через pty spawn . Таким образом, вы можете изменить свой шаблон регулярного выражения только для захвата этих символов:

 expect -re "(5.*)\r\n" set VERSION $expect_out(1,string) 

Обратите внимание, как мы запрашиваем индекс 1, capture () , а не 0, весь шаблон совпадает.

Кроме того, вы можете удалить пробелы командой tcl

 set VERSION [string trim $expect_out(0,string)] 

Обратите внимание, что вы смешиваете шаблоны glob и regexp в своей строке ожидания: 5.*.* Поскольку шаблон glob будет соответствовать вашему типу ввода 5.xx. Использование -re означает, что вам следует просто использовать regexp 5.* который соответствует всем концам.