Что за программа yes

Какую вы знаете самую простую команду Unix? Есть echo , которая печатает строку в stdout, и есть true , которая ничего не делает, а только завершается с нулевым кодом.

Среди множества простых Unix-команд спряталась команда yes . Если запустить её без аргументов, то вы получите бесконечный поток символов «y», каждый с новой строки:

y y y y (. ну вы поняли мысль)

Хотя на первый взгляд команда кажется бессмысленной, но иногда она бывает полезной:

yes | sh boring_installation.sh

Когда-нибудь устанавливали программу, которая требует ввести «y» и нажать Enter для установки? Команда yes приходит на помощь! Она аккуратно выполнит эту задачу, так что можете не отвлекаться от просмотра Pootie Tang.

Пишем yes

Вот базовая версия на… хм… BASIC.

10 PRINT «y» 20 GOTO 10

А вот то же самое на Python:

while True: print(«y»)

Кажется простым? Погодите!

Как выясняется, такая программа работает довольно медленно.

Лидерская программа для подростков YES!


python yes.py | pv -r > /dev/null [4.17MiB/s]

Сравните со встроенной версией на моём «маке»:

yes | pv -r > /dev/null [34.2MiB/s]

Так что я попытался написать более быструю версию на Rust. Вот моя первая попытка:

use std::env; fn main() < let expletive = env::args().nth(1).unwrap_or(«y».into()); loop < println!(«<>», expletive); > >

  • Строка, которую мы печатаем в цикле, — это первый параметр командной строки под названием expletive. Это слово я узнал из руководства yes .
  • Я использую unwrap_or , чтобы получить expletive из параметров. Если параметры не установлены, по умолчанию используется «y».
  • Параметр по умолчанию конвертируется из строкового фрагмента ( /dev/null Compiling yes v0.1.0 Finished release [optimized] target(s) in 1.0 secs Running `target/release/yes` [2.35MiB/s]

    Упс, ничего особенно не улучшилось. Она даже медленнее, чем версия на Python! Это меня заинтересовало, так что я поискал исходники реализации на C.

    Вот самая первая версия программы, которая вышла в составе Version 7 Unix за почётным авторством Кена Томпсона 10 января 1979 года:

    main(argc, argv) char **argv; < for (;;) printf(«%sn», argc>1? argv[1]: «y»); >

    Сравним со 128-строчной версией из комплекта GNU coreutils, зеркало которого есть на Github. После 25 лет программа всё ещё в активной разработке! Последнее изменение кода произошло около года назад. Она довольно быстрая:

    # brew install coreutils gyes | pv -r > /dev/null [854MiB/s]

    Важная часть находится в конце:

    /* Repeatedly output the buffer until there is a write error; then fail. */ while (full_write (STDOUT_FILENO, buf, bufused) == bufused) continue;

    Ага! Так здесь просто используется буфер для ускорения операций записи. Размер буфера устанавливается постоянной BUFSIZ , которая выбирается для каждой системы, чтобы максимально оптимизировать операции ввода-вывода (см. здесь). На моей системе она была установлена как 1024 байта.

    Лидерская программа для подростков YES!

    В реальности лучшая производительность оказалась при 8192 байтах.

    Я расширил свою программу Rust:

    use std::io::; const BUFSIZE: usize = 8192; fn main() < let expletive = env::args().nth(1).unwrap_or(«y».into()); let mut writer = BufWriter::with_capacity(BUFSIZE, io::stdout()); loop < writeln!(writer, «<>», expletive).unwrap(); > >

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

    Такая программа выдаёт 51,3 МиБ/с. Быстрее, чем версия, установленная в моей системе, но намного медленнее чем вариант от автора найденного мной поста на Reddit. Он говорит, что добился скорости 10,2 ГиБ/с.

    Дополнение

    Как обычно, сообщество Rust не подкачало. Как только эта статья попала в подреддит о Rust, пользователь nwydo указал на предыдущее обсуждение этой темы. Вот их оптимизированный код, который пробивает 3 ГБ/с на моей машине:

    use std::env; use std::io::; use std::process; use std::borrow::Cow; use std::ffi::OsString; pub const BUFFER_CAPACITY: usize = 64 * 1024; pub fn to_bytes(os_str: OsString) -> Vec < use std::os::unix::ffi::OsStringExt; os_str.into_vec() >fn fill_up_buffer(buffer: ‘a [u8]) -> if output.len() >buffer.len() / 2 < return output; >let mut buffer_size = output.len(); buffer[..buffer_size].clone_from_slice(output); while buffer_size < buffer.len() / 2 < let (left, right) = buffer.split_at_mut(buffer_size); right[..buffer_size].clone_from_slice(left); buffer_size *= 2; > fn write(output: let stdout = io::stdout(); let mut locked = stdout.lock(); let mut buffer = [0u8; BUFFER_CAPACITY]; let filled = fill_up_buffer( while locked.write_all(filled).is_ok() <>> fn main() < write(b»yn»[..], ), |mut arg| < arg.push(b’n’); Cow::Owned(arg) >, )); process::exit(1); >

    Так это же совсем другое дело!

    • Мы подготовили заполненный строковый буфер, который будет заново использоваться в каждом цикле.
    • Поток стандартного вывода (stdout) защищён блокировкой. Так что вместо непрерывного захвата и освобождения мы держим его всё время.
    • Используем нативные для платформы std::ffi::OsString и std::borrow::Cow , чтобы избежать ненужных размещений в памяти.

    Извлечённые уроки

    Тривиальная программа yes на самом деле оказалась не такой простой. Для улучшения производительности в ней используется буферизация вывода и выравнивание памяти.

    Переработка стандартных инструментов Unix — увлекательное занятие и оно заставляет ценить те изящные трюки, которые делают наши компьютеры быстрыми.

    Источник: habr.com

    Команда yes

    Команда yes в Linux

    Бесконечно выводит на экран заданную строку или y (да). Используется для автоматического подтверждения запросов других команд в командной строке.

    Синтаксис

    Без аргументов

    Если выполнить команду yes без каких либо аргументов, то на экран бесконечно будет выводиться символ «y» (каждый символ на новой строке). Данное поведение используется для автоматического подтверждения запросов, при выполнении других команд (см. примеры ниже).

    $ yes y y y y .

    С указанием строки

    yes строка

    Если для команды yes задать строку , то на экран будет бесконечно выводиться эта строка (каждая строка на новой строке).

    $ yes I am the best of the best I am the best of the best I am the best of the best I am the best of the best I am the best of the best .

    Опции

    У команды yes всего 2 опции:

    Вывести информацию о команде yes.
    Вывести версию утилиты yes.

    Примеры использования команды yes

    Обычно команда yes используется для того, чтобы при выполнении других команд или скриптов, которые выдают пользователю запросы, требующие ввести y (yes) или n (no), автоматически вводилось y (yes) на каждый запрос. То есть, чтобы избавить пользователя от необходимости самостоятельно отвечать y (Да) на каждый запрос.

    В какой-то степени данная команда уже устарела, потому что многие команды и скрипты имеют опции -y или -f (force), выполняющие аналогичные действия (принудительный ответ y (Да) на каждый запрос).

    Отвечаем Да на каждый запрос при восстановлении файловой системы

    При проверке файловой системы командой fsck могут выдаваться запросы на исправление ошибок в файловой системе. Чтобы автоматически отвечать Да на каждый запрос, можно использовать следующую команду:

    yes | fsck /dev/hdname

    Отвечаем Да при удалении файлов

    Выполним команду rm , чтобы удалить все файлы с расширением .txt

    yes | rm *.txt

    Данная команда эквивалентна команде:

    rm -f *.txt

    Создание большого файла

    Команда yes может использоваться для создания больших файлов, заполненных данными. Например, это может потребоваться при тестировании программ.

    Создадим файл myfile.txt и запишем в него 1000 одинаковых строк:

    yes ‘Some test text for the file’ | head -1000 > myfile.txt

    Источник: pingvinus.ru

    Как использовать команду yes в Linux

    toadmin.ru

    Команда yes кажется слишком простой, чтобы иметь какое-либо практическое применение, но в этом руководстве мы покажем вам ее применение и то, как извлечь выгоду из ее отложенного положительного результата в Linux и macOS.

    Команда yes

    Команда yes — одна из самых простых команд в Linux и других Unix-подобных операционных системах, таких как macOS. Под простым мы подразумеваем простоту в использовании и первоначальной реализации. Исходный код исходной версии — выпущен в System 7 Unix и автором Кен Томпсон— составляет всего лишь шесть строк кода.

    Но не списывайте это на простую маленькую команду. Его можно использовать несколькими интересными и полезными способами.

    Что делает да?

    При использовании без каких-либо параметров командной строки команда yes ведет себя так, как если бы вы вводили «y» и нажимали Enter, снова и снова (и снова и снова) снова. Очень быстро. И это будет продолжаться, пока вы не нажмете Ctrl + C, чтобы прервать его.

    вывод да в окне терминала

    Фактически, yes можно использовать для многократной генерации любого сообщения по вашему выбору. Просто введите да, пробел, строку, которую вы хотите использовать, а затем нажмите Enter. Это часто используется, чтобы заставить yes генерировать выходной поток строк «да» или «нет».

    yes yes

    вывод да да в окне терминала

    yes anything you like

    вывод из yes со строкой текста в окне терминала

    Но что в этом толку?

    Вывод yes может быть передан в другие программы или сценарии.

    Звучит знакомо? Вы запускаете долгий процесс и уходите, оставляя его работать. Когда вы вернетесь к своему компьютеру, процесс вообще не завершится. В ваше отсутствие он задал вам вопрос и сидит в ожидании ответа «да» или «нет».

    Если вы заранее знаете, что все ваши ответы будут положительными («да» или «y») или отрицательными («нет» или «n»), вы можете использовать «да», чтобы предоставить вам эти ответы. Затем ваш долгий процесс будет доведен до завершения без присмотра, и вы получите ответы на все вопросы, которые задает процесс.

    Как перейти с Windows 7 на Linux

    Использование да со скриптами

    Взгляните на следующий сценарий оболочки Bash. (Нам нужно представить, что это часть гораздо более крупного скрипта, выполнение которого займет значительное время.)

    #!/bin/bash # . # in the middle of some long script # obtain a response from the user # . echo «Are you happy to proceed? [y,n]» read input # did we get an input value? if [ «$input» == «» ]; then echo «Nothing was entered by the user» # was it a y or a yes? elif [[ «$input» == «y» ]] || [[ «$input» == «yes» ]]; then echo «Positive response: $input» # treat anything else as a negative response else echo «negative response: $input» fi

    Этот сценарий задает вопрос и ожидает ответа. Логический поток в сценарии определяется вводом пользователя.

    «Да» или «y» означает положительный ответ.
    Любой другой ввод считается отрицательным ответом.
    Нажатие Enter без ввода текста ничего не делает.

    Чтобы проверить это, скопируйте сценарий в файл и сохраните его как long_script.sh. Используйте chmod, чтобы сделать его исполняемым.

    chmod +x long_script.sh

    Запустите сценарий с помощью следующей команды. Попробуйте ввести «yes», «y» и что-нибудь еще в качестве ввода, включая нажатие Enter без ввода текста.

    ./long_script.sh

    вывод из long_script.sh в окне терминала

    Чтобы получить «да», чтобы предоставить наш ответ на вопрос сценария, направьте вывод «да» по конвейеру.

    yes | ./long_script.sh

    передача да в long_script.sh в окне терминала

    Некоторые сценарии более жесткие в своих требованиях и принимают только полное слово «да» как положительный ответ. Вы можете указать «да» в качестве параметра для «да» следующим образом:

    yes yes | ./long_script.sh

    трубопровод да да в long_script.sh в окне терминала

    Не говори «да», не задумываясь об этом

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

    Как использовать команду history в Linux

    Логика в сценарии, команде или программе может не соответствовать вашим ожиданиям. В нашем примере сценария вопрос мог быть таким: «Вы хотите остановиться? [y,n]. » Если бы это было так, отрицательный ответ позволил бы сценарию продолжить работу.

    Вы должны быть знакомы со сценарием, командой или программой, прежде чем беспечно вставлять в них «да».

    Использование yes с командами

    В младенчестве да будет использоваться с другими командами Linux. С тех пор большинство этих других команд Linux работают по-своему, без вмешательства человека. Да больше не требуется для этого.

    В качестве примера возьмем диспетчер пакетов Ubuntu apt-get. Чтобы установить приложение, не нажимая «y» в середине процесса установки, можно было бы использовать yes следующим образом:

    yes | sudo apt-get install fortune-mod

    передача да в apt-get в окне терминала

    Тот же результат может быть достигнут с помощью опции -y (предположим, что да) в apt-get:

    sudo apt-get -y install fortune-mod

    с помощью apt-get с опцией accept yes в окне терминала

    Вы увидите, что apt-get даже не спрашивал своего обычного: «Вы хотите продолжить? [Y/n]»Вопрос. Он просто предполагал, что ответ будет «да».

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

    yes | yum install fortune-mod

    Менеджер пакетов dnf заменил yum, а dnf имеет свой собственный параметр -y (предположим, что да).

    dnf -y install fortune-mod

    То же самое относится к cp, fsck и rm. Каждая из этих команд имеет свои собственные параметры -f (принудительно) или -y (предположим, что да).

    Неужели кажется, что yes было отнесено к работе только со скриптами? Не совсем. В старой собаке есть еще несколько уловок.

    Некоторые дополнительные да хитрости

    Вы можете использовать yes с последовательностью цифр, сгенерированной seq, чтобы управлять циклом повторяющихся действий.

    Этот однострочник отображает сгенерированные цифры в окно терминала, а затем вызывает спящий режим на одну секунду.

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

    yes «$(seq 1 20)» | while read digit; do echo digit; sleep 1; done

    да однострочный регулирующий цикл в окне терминала

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

    Как управлять аудиоустройствами в Linux с помощью Pavucontrol

    Вы можете быстро создавать большие файлы с помощью yes. Все, что вам нужно сделать, это дать ему длинную строку текста для работы и перенаправить вывод в файл. Не ошибитесь; эти файлы будут быстро расти. Будьте готовы нажать Ctrl + C в течение нескольких секунд.

    yes long line of meaningless text for file padding > test.txt
    ls -lh test.txt
    wc test.txt

    создание тестовых файлов с окном терминала yes ia

    Сгенерированный здесь файл занял около пяти секунд на тестовой машине, использованной для исследования этой статьи. ls сообщает, что его размер составляет 557 Мб, а мы сообщаем, что в нем 12,4 миллиона строк.

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru