Часто возникает необходимость, чтобы скрипт командного интерпретатора Bash выводил результат своей работы. По умолчанию он отображает стандартный поток данных — окно терминала. Это удобно для обработки результатов небольшого объёма или, чтобы сразу увидеть необходимые данные.
В интерпретаторе можно делать вывод в файл Bash. Применяется это для отложенного анализа или сохранения массивного результата работы сценария. Чтобы сделать это, используется перенаправление потока вывода с помощью дескрипторов.
Стандартные дескрипторы вывода
В системе GNU/Linux каждый объект является файлом. Это правило работает также для процессов ввода/вывода. Каждый файловый объект в системе обозначается дескриптором файла — неотрицательным числом, однозначно определяющим открытые в сеансе файлы. Один процесс может открыть до девяти дескрипторов.
В командном интерпретаторе Bash первые три дескриптора зарезервированы для специального назначения:
STDIN | Стандартный ввод | |
1 | STDOUT | Стандартный вывод |
2 | STDERR | Стандартный вывод ошибок |
#53. Запись данных в файл в текстовом и бинарном режимах | Python для начинающих
Их предназначение — обработка ввода/вывода в сценариях. По умолчанию стандартным потоком ввода является клавиатура, а вывода — терминал. Рассмотрим подробно последний.
Вывод в файл Bash
1. Перенаправление стандартного потока вывода
Для того, чтобы перенаправить поток вывода с терминала в файл, используется знак «больше» (>).
#!/bin/bash
echo «Строка 1»
echo «Промежуточная строка» > file
echo «Строка 2» > file
Как результат, «Строка 1» выводится в терминале, а в файл file записывается только «Строка 2»:
Связано это с тем, что > перезаписывает файл новыми данными. Для того, чтобы дописать информацию в конец файла, используется два знака «больше» (>>).
#!/bin/bash
echo «Строка 1»
echo «Промежуточная строка» > file
echo «Строка 2» >> file
Если во время использования перенаправления вывода интерпретатор обнаружит ошибку, то он не запишет сообщение о ней в файл.
#!/bin/bash
ls badfile > file2
echo «Строка 2» >> file2
В данном случае ошибка была в том, что команда ls не смогла найти файл badfile, о чём Bash и сообщил. Но вывелось сообщение в терминал, а не записалось в файл. Всё потому, что использование перенаправления потоков указывает интерпретатору отделять мух от котлет ошибки от основной информации.
Это особенно полезно при выполнении сценариев в фоновом режиме, где приходится предусматривать вывод сообщений в журнал. Но так как ошибки в него писаться не будут, нужно отдельно перенаправлять поток ошибок для того, чтобы выполнить их вывод в файл Linux.
Чтение и запись в файл с++ используя класс fstream c++. Изучение С++ для начинающих. Урок #118
2. Перенаправление потока ошибок
В командном интерпретаторе для обработки сообщений об ошибках предназначен дескриптор STDERR, который работает с ошибками, сформированными как от работы интерпретатора, так и самим скриптом.
По умолчанию STDERR указывает в то же место, что и STDOUT, хотя для них и предназначены разные дескрипторы. Но, как было показано в примере, использование перенаправления заставляет Bash разделить эти потоки.
Чтобы выполнить перенаправление вывода в файл Linux для ошибок, следует перед знаком«больше» указать дескриптор 2.
#!/bin/bash
ls badfile 2> errors
echo «Строка 1» > file3
echo «Строка 2» >> file3
В результате работы скрипта создан файл errors, в который записана ошибка выполнения команды ls, а в file3 записаны предназначенные строки. Таким образом, выполнение сценария не сопровождается выводом информации в терминал.
Пример того, как одна команда возвращает и положительный результат, и ошибку:
ls -lh test badtest 2> errors
Команда ls попыталась показать наличие файлов test и badtest. Первый присутствовал в текущем каталоге, а второй — нет. Но сообщение об ошибке было записано в отдельный файл.
Если возникает необходимость выполнить вывод команды в файл Linux, включая её стандартный поток вывода и ошибки, стоит использовать два символа перенаправления, перед которыми стоит указывать необходимый дескриптор.
ls -lh test test2 badtest 2> errors 1> output
Результат успешного выполнения записан в файл output, а сообщение об ошибке — в errors.
По желанию можно выводить и ошибки, и обычные данные в один файл, используя .
ls -lh test badtest output
Обратите внимание, что Bash присваивает сообщениям об ошибке более высокий приоритет по сравнению с данными, поэтому в случае общего перенаправления ошибки всегда будут располагаться в начале.
Временные перенаправления в скриптах
Если есть необходимость в преднамеренном формировании ошибок в сценарии, можно каждую отдельную строку вывода перенаправлять в STDERR. Для этого достаточно воспользоваться символом перенаправления вывода, после которого нужно использовать Это сообщение об ошибке» >Это нормальное сообщение»
При выполнении программы обычно нельзя будет обнаружить отличия:
Вспомним, что GNU/Linux по умолчанию направляет вывод STDERR в STDOUT. Но если при выполнении скрипта будет перенаправлен поток ошибок, то Bash, как и полагается, разделит вывод.
Этот метод хорошо подходит для создания собственных сообщений об ошибках в сценариях.
Постоянные перенаправления в скриптах
Если в сценарии необходимо перенаправить вывод в файл Linux для большого объёма данных, то указание способа вывода в каждой инструкции echo будет неудобным и трудоёмким занятием. Вместо этого можно указать, что в ходе выполнения данного скрипта должно осуществляться перенаправление конкретного дескриптора с помощью команды exec:
#!/bin/bash
exec 1> testout
echo «Это тест перенаправления всего вывода»
echo «из скрипта в другой файл»
echo «без использования временного перенаправления»
Вызов команды exec запускает новый командный интерпретатор и перенаправляет стандартный вывод в файл testout.
Также существует возможность перенаправлять вывод (в том числе и ошибок) в произвольном участке сценария:
#!/bin/bash
exec 2> testerror
echo «Это начально скрипта»
echo «И это первые две строки»
exec 1> testout
echo «Вывод сценария перенаправлен»
echo «из с терминала в другой файл»
echo «но эта строка записана в файл ошибок» >https://losst.pro/vyvod-v-fajl-bash-v-linux» target=»_blank»]losst.pro[/mask_link]
Записать результат работы функции в файл
Есть около 100 функций, которые в результате своей работы печатают в консоль много строк. Как в примере, но функции гораздо сложнее.
def print_lines(arg): for i in range(arg): print(‘line’, i)
ВНЕЗАПНО, понадобилось выводить результат работы этих функций в файл. Есть ли какой-то способ сделать это проще чем дублировать каждую функцию с записью в файл вместо print() или с возвратом списка строк вместо print()? Наверное правильно было изначально делать возврат списка строк. Но уже что есть то есть. UPD Решил вопрос так:
from contextlib import redirect_stdout def my_function(): print(‘some text’) with open(‘file_name.txt’, ‘w’) as f: with redirect_stdout(f): my_function()
Отслеживать
задан 13 янв 2020 в 10:44
59 1 1 серебряный знак 6 6 бронзовых знаков
15 янв 2020 в 9:54
15 янв 2020 в 10:12
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Можно в самом начале переопределить функцию print
old_print = print # Запоминаем старую функцию print def print(*args, **kwargs): # Переопределяем if «file» not in kwargs: # Если не передали параметр file with open(«filename», «a») as fp: # Будем записывать в файл filename old_print(*args, **kwargs, file=fp) else: old_print(*args, **kwargs) # Иначе будем записывать в file, который передали
Но это очень плохая практика. Если кто-то будет смотреть Ваш код (возможно даже Вы сами через некоторое время), то Вам за это «спасибо» не скажут. Другой способ: можно просто перенаправить stdout в файл. Для этого можно просто запустить скрипт так:
python script.py > filename
Тем самым всё будет печататься не в консоль, а в файл filename .
UPD (уже неактуально, но пусть будет)
Если Вы хотите выполнить только одну функцию из скрипта, то придётся в самом скрипте подключать модуль sys (встроенный) и смотреть параметры, переданные скрипту из командой строки. Например:
import sys def func1(*args): print(args) # Функционал функции def func2(*args): print(args) # Функционал функции # . def run_all_funcs(): # запускает все функции func1() func2() # . if __name__ == «__main__»: if len(sys.argv) == 2: # Проверяем кол-во аргументов, # переданных скрипту из командой строки if sys.argv[1] == «func1»: func1() if sys.argv[1] == «func2»: func2() # . else: # Если аргументов не передали, то запускаем все функции run_all_funcs()
И запуск тогда будет такой:
python script.py func2 > filename
Надеюсь, суть ясна.
UUPD
Сразу не подумал, можно намного проще. Если в файле script.py есть функция func(a, b) , то только её можно вызвать так:
python -c «from script import *; func(1, 2)» > filename
Обратите внимание, что мы импортируем всё из файла script.py , но расширение .py не указываем.
Источник: ru.stackoverflow.com
Выполнение базового файлового ввода-вывода в Visual C++
В этой статье описывается выполнение основных операций ввода-вывода файлов в Microsoft Visual C++ или Visual C++ .NET.
Исходная версия продукта: Visual C++
Исходный номер базы знаний: 307398
Аннотация
Если вы не знакомы с платформа .NET Framework, вы обнаружите, что объектная модель для операций с файлами в платформа .NET Framework похожа FileSystemObject на модель, которая пользуется популярностью у многих разработчиков Visual Studio.
- Чтобы упростить переход, см . статью Использование FileSystemObject с Помощью Visual Basic.
- Сведения о версии .NET для Visual C# этой статьи см. в статье Как выполнить базовый файловый ввод-вывод в Visual C#.
В этой статье рассматриваются следующие платформа .NET Framework пространства имен библиотек классов:
- System::ComponentModel
- System::Windows::Forms
- System::Drawing
Вы по-прежнему FileSystemObject можете использовать в платформа .NET Framework. FileSystemObject Так как является компонентом COM, платформа .NET Framework требует, чтобы доступ к объекту проходил через слой взаимодействия. Если вы хотите его использовать, платформа .NET Framework создает оболочку для компонента. File Однако класс, FileInfo класс , Directory DirectoryInfo классы и другие связанные классы в платформа .NET Framework предоставляют функциональные возможности, недоступные в FileSystemObject , без накладных расходов на уровень взаимодействия.
Демонстрация операций ввода-вывода файлов
В примерах в этой статье описываются основные операции ввода-вывода файлов. В разделе Пошаговый пример описывается создание примера программы, демонстрирующей следующие шесть операций ввода-вывода файлов:
- Чтение текстового файла
- Запись текстового файла
- Просмотр сведений о файлах
- Вывод списка дисков
- Вывод списка вложенных папок
- Вывод списка файлов
Чтение текстового файла
В следующем примере кода класс используется StreamReader для чтения текстового файла. Содержимое файла добавляется в элемент управления ListBox. Блок try. catch используется для оповещения программы, если файл пуст. Существует множество способов определить, когда достигается конец файла. В этом примере метод используется Peek для изучения следующей строки перед ее чтением.
listBox1->Items->Clear(); try < String* textFile = String::Concat(windir, (S»\mytest.txt»)); StreamReader *reader=new StreamReader(textFile); do < listBox1->Items->Add(reader->ReadLine()); > while(reader->Peek() != -1); > catch (System::Exception *e) < listBox1->Items->Add(e); >
В Visual C++ необходимо добавить параметр компилятора поддержки среды CLR (/clr:oldSyntax), чтобы успешно скомпилировать предыдущий пример кода как управляемый C++. Чтобы добавить параметр компилятора поддержки среды CLR, выполните следующие действия.
Примечание.
— это заполнитель для имени проекта.
Запись текстового файла
Этот пример кода использует класс для StreamWriter создания и записи в файл. Если у вас есть существующий файл, его можно открыть таким же образом.
StreamWriter* pwriter = new StreamWriter(S»c:\KBTest.txt»); pwriter->WriteLine(S»File created using StreamWriter class.»); pwriter->Close(); listBox1->Items->Clear(); String *filew = new String(S»File Written to C:\KBTest.txt»); listBox1->Items->Add(filew);
Просмотр сведений о файлах
В этом примере кода для доступа к свойствам файла используется FileInfo класс . в этом примере используется Notepad.exe. Свойства отображаются в элементе управления ListBox.
listBox1->Items->Clear(); String* testfile = String::Concat(windir, (S»\notepad.exe»)); FileInfo *pFileProps =new FileInfo(testfile); listBox1->Items->Add(String::Concat(S»File Name = «, (pFileProps->get_FullName()))); listBox1->Items->Add(String::Concat(S»Creation Time = «, (pFileProps->get_CreationTime()).ToString())); listBox1->Items->Add(String::Concat(S»Last Access Time = » ,(pFileProps->get_LastAccessTime()).ToString())); listBox1->Items->Add(String::Concat(S»Last Write Time = «, (pFileProps->get_LastWriteTime()).ToString())); listBox1->Items->Add(String::Concat(S»Size = «, (pFileProps->get_Length()).ToString()));
Вывод списка дисков
В этом примере кода классы и Drive используются Directory для вывода списка логических дисков в системе. В этом примере результаты отображаются в элементе управления ListBox.
listBox1->Items->Clear(); String* drives[] = Directory::GetLogicalDrives(); int numDrives = drives->get_Length(); for (int i=0; iItems->Add(drives[i]); >
Вывод списка вложенных папок
Этот пример кода использует GetDirectories метод класса для Directory получения списка папок.
listBox1->Items->Clear(); String* dirs[] = Directory::GetDirectories(windir); int numDirs = dirs->get_Length(); for (int i=0; iItems->Add(dirs[i]); >
Вывод списка файлов
В этом примере кода метод класса используется GetFiles Directory для получения списка файлов.
listBox1->Items->Clear(); String* files[]= Directory::GetFiles(this->windir); int numFiles = files->get_Length(); for (int i=0; iItems->Add(files[i]); >
Многие вещи могут пойти не так, когда пользователь получает доступ к файлам. Файлы могут не существовать, файлы могут использоваться или пользователи могут не иметь прав на файлы папок, к которым они пытаются получить доступ. Учитывайте эти возможности при написании кода для обработки исключений, которые могут быть созданы.
Пошаговый пример
- Запустите Visual Studio .NET.
- В меню Файл выберите пункт Создать и затем пункт Проект.
- В разделе Типы проектов щелкните Проекты Visual C++. В разделе Шаблоны щелкните Windows Forms приложение (.NET).
- Введите KB307398 в поле Имя , введите C: в поле Расположение и нажмите кнопку ОК.
- Откройте форму Form1 в режиме конструктора и нажмите клавишу F4, чтобы открыть окно Свойства .
- В окне Свойства разверните папку Размер . В поле Ширина введите 700. В поле Высота введите 320.
- Добавьте один элемент управления ListBox и шесть элементов управления Button в Form1.
Примечание. Чтобы просмотреть панель элементов, щелкните Панель элементов в меню Вид .
private: String *windir;
windir = System::Environment::GetEnvironmentVariable(«windir»);
// How to read a text file: // Use try. catch to deal with a 0 byte file or a non-existant file. listBox1->Items->Clear(); try < String* textFile = String::Concat(windir, (S»\mytest.txt»)); StreamReader *reader=new StreamReader(textFile); do < listBox1->Items->Add(reader->ReadLine()); > while(reader->Peek() != -1); > catch(FileNotFoundException *ex) < listBox1->Items->Add(ex); > catch (System::Exception *e) < listBox1->Items->Add(e); >
// This demonstrates how to create and to write to a text file.
StreamWriter* pwriter = new StreamWriter(S»c:\KBTest.txt»); pwriter->WriteLine(S»The file was created by using the StreamWriter class.»); pwriter->Close(); listBox1->Items->Clear(); String *filew = new String(S»File written to C:\KBTest.txt»); listBox1->Items->Add(filew);
// This code retrieves file properties.
The example uses Notepad.exe. listBox1->Items->Clear(); String* testfile = String::Concat(windir, (S»\notepad.exe»)); FileInfo *pFileProps =new FileInfo(testfile); listBox1->Items->Add(String::Concat(S»File Name = «, (pFileProps->get_FullName()))); listBox1->Items->Add(String::Concat(S»Creation Time = «, (pFileProps->get_CreationTime()).ToString())); listBox1->Items->Add(String::Concat(S»Last Access Time = » ,(pFileProps->get_LastAccessTime()).ToString())); listBox1->Items->Add(String::Concat(S»Last Write Time = «, (pFileProps->get_LastWriteTime()).ToString())); listBox1->Items->Add(String::Concat(S»Size = «, (pFileProps->get_Length()).ToString()));
// This demonstrates how to obtain a list of disk drives. listBox1->Items->Clear(); String* drives[] = Directory::GetLogicalDrives(); int numDrives = drives->get_Length(); for (int i=0; iItems->Add(drives[i]); >
// This code obtains a list of folders. This example uses the Windows folder. listBox1->Items->Clear(); String* dirs[] = Directory::GetDirectories(windir); int numDirs = dirs->get_Length(); for (int i=0; iItems->Add(dirs[i]); >
// This code obtains a list of files. This example uses the Windows folder. listBox1->Items->Clear(); String* files[]= Directory::GetFiles(this->windir); int numFiles = files->get_Length(); for (int i=0; iItems->Add(files[i]); >
Полный пример кода
//Form1.h #pragma once namespace KB307398 < using namespace System; using namespace System::IO; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// /// Summary for Form1 /// WARNING: If you change the name of this class, you will need to change the /// ‘Resource File Name’ property for the managed resource compiler tool /// associated with all .resx files this class depends on. Otherwise, /// the designers will not be able to interact properly with localized /// resources associated with this form. /// public __gc class Form1 : public System::Windows::Forms::Form < private: String *windir; public: Form1(void) < windir = System::Environment::GetEnvironmentVariable(«windir»); InitializeComponent(); >protected: void Dispose(Boolean disposing) < if (disposing components) < components->Dispose(); > __super::Dispose(disposing); > private: System::Windows::Forms::Button * button1; private: System::Windows::Forms::Button * button2; private: System::Windows::Forms::Button * button3; private: System::Windows::Forms::Button * button4; private: System::Windows::Forms::Button * button5; private: System::Windows::Forms::Button * button6; private: System::Windows::Forms::ListBox * listBox1; private: /// /// Required designer variable. /// System::ComponentModel::Container * components; /// /// Required method for Designer support — do not modify /// the contents of this method with the code editor. /// void InitializeComponent(void) < this->button1 = new System::Windows::Forms::Button(); this->button2 = new System::Windows::Forms::Button(); this->button3 = new System::Windows::Forms::Button(); this->button4 = new System::Windows::Forms::Button(); this->button5 = new System::Windows::Forms::Button(); this->button6 = new System::Windows::Forms::Button(); this->listBox1 = new System::Windows::Forms::ListBox(); this->SuspendLayout(); // button1 this->button1->Location = System::Drawing::Point(500, 32); this->button1->Name = S»button1″; this->button1->Size = System::Drawing::Size(112, 23); this->button1->TabIndex = 1; this->button1->Text = S»Read Text File»; this->button1->Click += new System::EventHandler(this, button1_Click); // button2 this->button2->Location = System::Drawing::Point(500, 64); this->button2->Name = S»button2″; this->button2->Size = System::Drawing::Size(112, 23); this->button2->TabIndex = 2; this->button2->Text = S»Write Text File»; this->button2->Click += new System::EventHandler(this, button2_Click); // button3 this->button3->Location = System::Drawing::Point(500, 96); this->button3->Name = S»button3″; this->button3->Size = System::Drawing::Size(112, 23); this->button3->TabIndex = 3; this->button3->Text = S»View File Information»; this->button3->Click += new System::EventHandler(this, button3_Click); // button4 this->button4->Location = System::Drawing::Point(500, 128); this->button4->Name = S»button4″; this->button4->Size = System::Drawing::Size(112, 23); this->button4->TabIndex = 4; this->button4->Text = S»List Drives»; this->button4->Click += new System::EventHandler(this, button4_Click); // button5 this->button5->Location = System::Drawing::Point(500, 160); this->button5->Name = S»button5″; this->button5->Size = System::Drawing::Size(112, 23); this->button5->TabIndex = 5; this->button5->Text = S»List Subfolders»; this->button5->Click += new System::EventHandler(this, button5_Click); // button6 this->button6->Location = System::Drawing::Point(500, 188); this->button6->Name = S»button6″; this->button6->Size = System::Drawing::Size(112, 23); this->button6->TabIndex = 6; this->button6->Text = S»List Files»; this->button6->Click += new System::EventHandler(this, button6_Click); // listBox1 this->listBox1->Location = System::Drawing::Point(24, 24); this->listBox1->Name = S»listBox1″; this->listBox1->Size = System::Drawing::Size(450, 199); this->listBox1->TabIndex = 0; // Form1 this->AutoScaleBaseSize = System::Drawing::Size(5, 13); this->ClientSize = System::Drawing::Size(692, 293); this->Controls->Add(this->listBox1); this->Controls->Add(this->button6); this->Controls->Add(this->button5); this->Controls->Add(this->button4); this->Controls->Add(this->button3); this->Controls->Add(this->button2); this->Controls->Add(this->button1); this->Name = S»Form1″; this->Text = S»Form1″; this->ResumeLayout(false); > private: System::Void button1_Click(System::Object * sender, System::EventArgs * e) < // This code shows how to read a text file. // The try. catch code is to deal with a 0 byte file or a non-existant file. listBox1->Items->Clear(); try < String* textFile = String::Concat(windir, (S»\mytest.txt»)); StreamReader *reader=new StreamReader(textFile); do < listBox1->Items->Add(reader->ReadLine()); > while(reader->Peek() != -1); > catch(FileNotFoundException *ex) < listBox1->Items->Add(ex); > catch (System::Exception *e) < listBox1->Items->Add(e); > > private: System::Void button2_Click(System::Object * sender, System::EventArgs * e) < // This code demonstrates how to create and to write to a text file.
StreamWriter* pwriter = new StreamWriter(S»c:\KBTest.txt»); pwriter->WriteLine(S»The file was created by using the StreamWriter class.»); pwriter->Close(); listBox1->Items->Clear(); String *filew = new String(S»The file was written to C:\KBTest.txt»); listBox1->Items->Add(filew); > private: System::Void button3_Click(System::Object * sender, System::EventArgs * e) < // This code retrieves file properties. This example uses Notepad.exe. listBox1->Items->Clear(); String* testfile = String::Concat(windir, (S»\notepad.exe»)); FileInfo *pFileProps =new FileInfo(testfile); listBox1->Items->Add(String::Concat(S»File Name = «, (pFileProps->get_FullName() )) ); listBox1->Items->Add(String::Concat(S»Creation Time = «, (pFileProps->get_CreationTime() ).ToString()) ); listBox1->Items->Add(String::Concat(S»Last Access Time = » ,(pFileProps->get_LastAccessTime() ).ToString()) ); listBox1->Items->Add(String::Concat(S»Last Write Time = «, (pFileProps->get_LastWriteTime() ).ToString()) ); listBox1->Items->Add(String::Concat(S»Size = «, (pFileProps->get_Length() ).ToString()) ); > private: System::Void button4_Click(System::Object * sender, System::EventArgs * e) < // The code demonstrates how to obtain a list of disk drives. listBox1->Items->Clear(); String* drives[] = Directory::GetLogicalDrives(); int numDrives = drives->get_Length(); for (int i=0; iItems->Add(drives[i]); > > private: System::Void button5_Click(System::Object * sender, System::EventArgs * e) < // This code obtains a list of folders.
This example uses the Windows folder. listBox1->Items->Clear(); String* dirs[] = Directory::GetDirectories(windir); int numDirs = dirs->get_Length(); for (int i=0; iItems->Add(dirs[i]); > > private: System::Void button6_Click(System::Object * sender, System::EventArgs * e) < // This code obtains a list of files. This example uses the Windows folder. listBox1->Items->Clear(); String* files[]= Directory::GetFiles(this->windir); int numFiles = files->get_Length(); for (int i=0; iItems->Add(files[i]); > > >; > //Form1.cpp #include «stdafx.h» #include «Form1.h» #include using namespace KB307398; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) < System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA; Application::Run(new Form1()); return 0; >
Ссылки
Дополнительные сведения см. в разделе служба поддержки Майкрософт. Дополнительные сведения о создании Форм Windows Forms в управляемых расширениях для C++ см. в примере справки ManagedCWinFormWiz visual Studio .NET.
Источник: learn.microsoft.com