Получить вывод команды командной оболочки в переменную makefile

Есть папка. В ней лежит makefile и еще пару папок с файлами:

директория

Допустим, что в папке third_pracice есть файл a.txt, который мне надо удалить через makefile:

введите сюда описание изображения

В makefile я написал такую цель:

clean: rm ./third_pracice/a.txt

Когда я запускаю make, то он выдает ошибку:

PS C:\Users\cashr\Desktop\pracice\cmp> make clean
rm ./third_pracice/a.txt
process_begin: CreateProcess(NULL, rm ./third_pracice/a.txt, ...) failed.
make (e=2): Ia oaaaony iaeoe oeacaiiue oaee.
makefile:2: recipe for target 'clean' failed
make: *** [clean] Error 2

В чем проблема? Если закинуть эту команду напрямую в терминал, то проблем нет. Пробовал использовать указание “sudo”, не помогло. Как работает удаление из других папок через make?

ОС – Windows

MarianD's user avatar

4 золотых знака21 серебряный знак32 бронзовых знака

задан 9 сент. 2023 в 17:56

Fidel Castro's user avatar

Я бы del не использовал. Нужно стремиться к кросс-платформенным мейкфайлам, а del – чисто виндовая вещь.

Если у вас не работает rm, значит вы либо скачали не тот Make, либо как-то странно его запускаете.

Снесите ваш Make. Поставьте MSYS2. Там запустите pacman -S mingw-w64-ucrt-x86_64-make, чтобы установить их версию Make, и потом запускайте mingw32-make из консоли MSYS2 (ярлык MSYS2 UCRT64 в меню пуск). (Есть еще просто make, который ставится из pacman -S make – он тормозит сильнее, и для вашего случая никакой другой разницы нет.)

ответ дан 10 сент. 2023 в 4:18

HolyBlackCat's user avatar

3 золотых знака28 серебряных знаков40 бронзовых знаков

clean: rm ./third_pracice/a.txt
clean: del .\third_pracice\a.txt

потому что команде rm (POSIX) соответствует команда del (Windows) и слеши (/) обратная слеш (\).

ответ дан 9 сент. 2023 в 22:12

MarianD's user avatar

4 золотых знака21 серебряный знак32 бронзовых знака

В терминале у вас запущен интерпретатор команд powershell. В нем rm является алиасом для командлета Remove-Item. Утилита make не является интерпретатором команд и не использует powershell, для выполнения каждой директивы она тупо запускает дочерний процесс. Соответственно чтобы rm работало в make необходимо, чтобы в PATH присутствовал исполняемый файл rm (rm.exe), который обычно распространяется как часть posix coreutils или их суррогатов. Так что если собираетесь использовать rm, то make необходимо запускать из окружения, где они уже установлены, например из ранееупомянутого msys или из git bash.

ответ дан 10 сент. 2023 в 6:25

user7860670's user avatar

3 золотых знака17 серебряных знаков36 бронзовых знаков

При обработке makefile в nmake требуется получить номер версии powershell для дальнейшей её проверки и работы с ней.
Пробовал назначить переменную окружения, но как‐то не получается.

psversion:
!IF [for /F %i in ('powershell $$psversiontable.psversion.major') do @set PSvr=%i]
!ENDIF

Пробовал напрямую проверять номер версии, тоже не работает. В этом случае, как я понимаю, ожидается код завершение, а не возвращаемое значение.

psversion:
! IF [powershell $$PSVersionTable.PSVersion.major] <= 2
! ERROR
! ENDIF

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

psversion:
psvr = [powershell $$PSVersionTable.PSVersion.major]
! IF $(psvr) <= 2
! ERROR
! ENDIF

В общем, идеи закончились. Как надо сделать?


  • Вопрос задан

2.
не имею ни малейшего представления насчёт фич nmake, но может быть, у него есть что-то, что проверяет, например, дату создания/редактирования файла ? тогда можно обойтись без запуска самого powershell.

Кстати, переменная $PSVersionTable появилась именно в v2, поэтому проверка типа IF $(psvr) <= 2 вам вообще недоступна, в принципе 🙂

3. Если nmake умеет обрабатывать код возврата, то можно так:

powershell -nologo -noprofile "exit $psversiontable.psversion.major"

В коде возврата версию вернёт
проверял на батнике

@powershell -nologo -noprofile "exit $psversiontable.psversion.major"
@echo %ERRORLEVEL%

Итак, решение, устраивающее в этой ситуации и для этой задачи, было найдено.
Благодаря подсказке MaxKozlov и исходя из сказанного в документации:

Another way to use exit codes is during preprocessing. You can run a command
or program and test its exit code using the !IF preprocessing directive. For more
information, see “Executing a Program in Preprocessing” on page 575.

chkpsver :
! IF [powershell -nologo -noprofile "exit $$psversiontable.psversion.major"] == 2
! ERROR Для работы требуется версия программы «PowerShell» версии 3.0 или выше
! ELSE
! MESSAGE ok
! ENDIF

Также можно использовать вариант с stackoverflow.com , на который указал MaxKozlov , или ещё одна реализация , и которые основываются на положениях документации:

Calling NMAKE Recursively
In a commands block, you can specify a call to NMAKE itself. Either invoke
the MAKE macro or specify NMAKE literally. The following NMAKE
information is available to the called NMAKE session during recursion:
� Environment-variable macros (see “Inherited Macros” on page 563). To
cause all macros to be inherited, specify the /V option.
� The MAKEFLAGS macro. If .IGNORE (or !CMDSWITCHES +I) is set,
MAKEFLAGS contains an I when it is passed to the recursive call.
Likewise, if .SILENT (or !CMDSWITCHES +S) is set, MAKEFLAGS
contains an S when passed to the call.
� Macros specified on the command line for the recursive call.
� All information in TOOLS.INI.
Inference rules defined in the makefile are not passed to the called NMAKE
session. Settings for .SUFFIXES and .PRECIOUS are also not inherited.
However, you can make .SUFFIXES, .PRECIOUS, and all inference rules
available to the recursive call either by specifying them in TOOLS.INI or by
placing them in a file that is specified in an !INCLUDE directive in the makefile
for each NMAKE session.

Другие варианты пока не проверены, но попробовать можно будет, когда найдётся время.

В командной строке:

for /F %i in ('powershell.exe $PSVersionTable.PSVersion.Major') do set PSVER=%i

Если вставляете в командный файл – замените %i на %%i


DBI

от 40 000 ₽

16 июл. 2024, в 22:38

5000 руб./за проект

16 июл. 2024, в 22:20

100000 руб./за проект

16 июл. 2024, в 22:16

70000 руб./за проект

Если вы читаете данную заметку, то скорее всего уже знаете, что такое Makefile и как с ним можно работать в своих проектах при написании программного кода.

Для запуска команд из Makefile необходима программа GNU Make. Если в Linux системах её просто установить и сразу можно с ней работать в среде разработки, то в Windows необходимо настроить окружение для корректной работы.

:/>  Как передать аргументы в пакетный файл?

Если не настроить окружение Windows, то получим в терминале Visual Studio Code ошибку:

make: Имя "make" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Проверьте правильность написания имени, а также наличие и правильность пути, после чего повторите попытку.

Установим и настроим GNU Make.

Установить GNU Make

Установить на Windows его можно несколькими способами.

Способ № 1

Запустить в PowerShell команду:

winget install GnuWin32.Make

Произойдёт скачивание и установка программы.

Способ № 2

Настроить GNU Make

После установки исполняемый файл программы доступен по пусти C:\Program Files (x86)\GnuWin32\bin. Убедитесь, что у вас программа установлена по данному пути. Если программа установилась по другому пути, то в настройках, которые описаны ниже, указывайте ваш путь.

Этот пусть необходимо прописать в системные переменные среды операционной системы. Для этого открыть Параметры и в строке поиска набрать Среды. Во всплывающей подсказке выбрать Изменение системных переменных среды:

Изменение системных переменных среды Windows

Далее в свойствах системы выбираем Переменные среды:

Cвойства системы, переменные среды Windows

В открывшемся окне в разделе Системные переменные ищем переменную Path и изменяем её, добавив требуемый путь:

Системные переменные, переменная Path
Системные переменные Windows, изменить переменную Path

В Visual Studio Code необходимо установить расширение Makefile Tools:

Makefile Tools

Перезапустить Visual Studio Code. Теперь можно запускать команды прописанные в Makefile вашего проекта.

Add CLI instructions behind one simple command

Kevin van Schaijk

Photo by Douglas Lopes on Unsplash

You’re familiar with the situation: you’re in the process of developing an application, and you have a CLI (Command Line Interface) command that you want to execute to start your Flutter app. You either take out a notepad or look up the command again. Then, when you need to perform a database migration in your backend, you have to search for that command as well.

Fortunately, it only takes a minute, and you can get back to work. However, this repetition occurs every day you’re working on it.

But there’s a solution to this problem. You can use a Makefile!

What is a Makefile?

A Makefile is a build automation tool that executes terminal commands through a text file with instructions. It can be used for various purposes, such as building apps, setting up deployment processes, and defining development processes with a simple command.

Using a Makefile comes with many advantages.

In the example below, you’ll find a Makefile in which I’ve included several .NET and Docker-related commands. Of course, this is a simple setup, but it provides a solid foundation for automating your command-line actions.

run:
docker-compose -f "../docker-compose.yml" up -d --build

stop:
docker-compose -f "../docker-compose.yml" stop

fix:
dotnet format
#additional checks you want to run

watch:
dotnet watch

If you want to use variables, you can use them like this:

How to get started?

Starting with a Makefile is very straightforward. When you have a Unix-based system (Linux, macOS), make is often already installed. Only Windows may require some additional installation steps.

  • Chocolatey (Recommended): Chocolatey is a package manager for Windows. You can install make using Chocolatey by running the following command in PowerShell or Command Prompt with administrator privileges:
choco install make

I recommend using Chocolatey for a hassle-free installation experience.

  • Alternative (GNUwin32): Another option for Windows is GNUwin32. You can download make from the following URL: GNUwin32 Make. However, please note that I haven’t tested the GNUwin32 method, and I recommend using Chocolatey for a smoother installation process.

For Linux (e.g., Ubuntu):

sudo apt-get install make

In case make is not installed or if you don’t see version information, you can obtain it through a package manager like Homebrew.

brew install make

Usecase examples

A few usecases you could use this files

1: Building and compiling code

One of the obvious options is to build and compile your application so that you can run it and prepare it for deployment to an actual environment.

In the example below, there is a .NET makefile that demonstrates some of these actions:

2: Running tests and QA (quality Assurance)

I personally like to use a Makefile to run various types of automated tests and check code quality.

Below is an example of a quality assurance Makefile for a PHP application, where, among other things, unit tests are run with PHPUnit, Behat tests are executed as behavior-driven tests, and various code style and linting checks/fixes are performed.

This way, you can easily run commands while developing, and you could also use the Makefile in your CI/CD pipelines to make quality testing a part of the process.

# PHP Quality Assurance Makefile

# PHP executable
PHP = php

# Directory for PHP source code
SRC_DIR = src

# Directory for tests
TEST_DIR = tests

# Run tests using PHPUnit
test:
$(PHP) vendor/bin/phpunit $(TEST_DIR)

# Run Behat tests
behat:
$(PHP) vendor/bin/behat

# Run PHP linter (PHP_CodeSniffer)
lint:
$(PHP) vendor/bin/phpcs $(SRC_DIR)

# Format PHP code using PHP-CS-Fixer
format:
$(PHP) vendor/bin/php-cs-fixer fix $(SRC_DIR) --using-cache=no

# Check code style using PHP-CS-Fixer
check-style:
$(PHP) vendor/bin/php-cs-fixer fix $(SRC_DIR) --using-cache=no --dry-run

# Perform all quality assurance checks
qa: test behat lint check-style

3: Development related tasks

In addition to actually building the application, you often have various actions that you perform frequently, such as generating new database migrations, updating the database, and running the project with hot-reload functionality. These actions can also be conveniently included in a Makefile, so you don’t have to look up the commands each time, and you can easily execute the actions.

Of course, you can customize these actions to suit your needs and go beyond using just one command.

In the example below, there are some .NET development commands.

# .NET API Development Makefile

# Variables
DOTNET = dotnet
API_PROJECT = MyApiProject/MyApiProject.csproj
DB_CONTEXT = MyDbContext
MIGRATIONS_DIR = Data/Migrations

# Add a new migration to the database
add-migration:
$(DOTNET) ef migrations add YourMigrationName --context $(DB_CONTEXT) --output-dir $(MIGRATIONS_DIR)

# Create a new migration script
create-migration:
$(DOTNET) ef migrations script -o $(MIGRATIONS_DIR)/YourMigrationScript.sql --context $(DB_CONTEXT)

# Update the database
update-database:
$(DOTNET) ef database update --context $(DB_CONTEXT)

# Run the .NET API using dotnet watch
watch:
$(DOTNET) watch run --project $(API_PROJECT)

Finally, a good use case would, of course, also be the deployment of the application, allowing you to easily incorporate processes that build your application and set it up in the environment, wherever it may be.

:/>  Как поменять обои на компьютере без активации виндовс

This can also be used in your CI/CD pipelines to easily configure deployment processes.

In the example below, there are some .NET deployment commands.

IDE plugins

If you use Visual Studio Code or JetBrains as your IDE editor, it’s also possible to use an IDE plugin.

With these plugins, you’ll get an overview of the commands, and you can easily run various make commands from your IDE environment.

I hope you found my tips on using a makefile useful. Do you have any good additions? Let us know in the comments!

Requirement: Create a file in PowerShell.

  • Create empty files with New-Item
  • Populate new files with content using Out-File
  • Create files from existing content with Set-Content
  • Overwrite existing files or append to them
  • Generate files based on conditions

With just a few PowerShell commands, you can rapidly generate any type of text or data file needed. By the end of this article, you’ll have a solid understanding of how to create and prepopulate files using PowerShell for everyday file management tasks and automation. Let’s get started!

PowerShell Commands for File Creation

How do you create a text file in a directory in PowerShell? Well, PowerShell has several commands that can be used to create files. These commands are easy to use and can be executed from the PowerShell console or PowerShell ISE. Here are some of the PowerShell commands for file creation.

New-Item

New-Item
[-Path] <path>
-ItemType File
[-Value <Object>]
[-Force]
[-Confirm]
[<CommonParameters>]

Here is an example of creating a new file using the New-Item cmdlet:

New-Item -Path "C:\Logs\NewLog1.txt" -ItemType File

This command creates a new empty file named “NewLog1.txt” in the specified path. You can verify by navigating to the specified path through File Explorer.

Out-File

"Hello World" | Out-File -FilePath "C:\Logs\NewLog2.txt"

This command creates a new file named “NewLog2.txt” and writes the text “Hello World” to the file.

Set-Content

Set-Content -Path "C:\Logs\NewLog3.txt" -Value "Hello World"

This command creates a new file named “NewLog3.txt” and writes the text “Hello World” to the file.

Creating a Text File in PowerShell

New-Item -ItemType File -Path .\newfile.txt

The New-Item cmdlet requires the -Path parameter, which specifies the location of the new file, and the -ItemType parameter, which specifies the type of item to create. To create a file, you need to set the -ItemType parameter to “File”. You can replace the file extension “txt” with any other type, such as “html” or “log”.

PowerShell Script to Create Multiple Files

1..3 | ForEach-Object { New-Item -Path "C:\Users\UserName\Documents\File$_" -ItemType File
}

This script creates three files named “File1.txt”, “File2.txt”, and “File3.txt” in the specified path.

Creating Files with Unique Names – TimeStamp

Creating uniquely named files is a frequent requirement in scripting and automation. PowerShell’s flexibility shines here, as it allows you to create files with unique names effortlessly.

Consider this example:

#Get the Timestamp
$Date = Get-Date -Format "yyyyMMdd_HHmmss"
#Create a new file with Timestamp
New-Item -Path "C:\Logs" -Name "Log_$date.txt" -ItemType "File"

This command creates a uniquely named log file, including the current date and time, ensuring each file has a unique name.

create a unique file name with timestamp powershell

Adding Content to a Text File in PowerShell

The Add-Content cmdlet can add content to a text file in PowerShell. By default, the Add-Content cmdlet appends content to the end of a file. Here is an example of how to append content to a text file:

Add-Content -Path "C:\Logs\NewLog.txt" -Value "This is some more text."

This command appends the text “This is some more text.” to the end of the file.

PowerShell to Create a File if not exists

You can also use the Test-Path cmdlet to check if the file exists before using the New-Item cmdlet to create it. The Test-Path cmdlet returns $true if the file exists and $false if it does not. Here’s an example of how you can use the Test-Path cmdlet to check if the file exists before creating it:

$FilePath = "C:\Temp\MyFile.txt"
#Check if file exists
if (Test-Path $FilePath) { Write-host "File '$FilePath' already exists!" -f Yellow
}
Else { #Create a new file New-Item -Path $FilePath -ItemType "File" Write-host "New File '$FilePath' Created!" -f Green
}

This code will check if the “MyFile.txt” file exists in the “C:\Temp” folder. If the file does not exist, it will create a new file using the New-Item cmdlet. If the file already exists, it will not do anything.

powershell create file

You can also use the Get-ChildItem cmdlet to check if a specified file exists.

$FilePath = "C:\Temp\TestFile.txt"
if(!(Get-ChildItem -Path $FilePath -Force -ErrorAction SilentlyContinue)) { New-Item -Path $FilePath -ItemType File -Value "Test File" Write-host "File '$FilePath' created successfully!"
} else { Write-host "File '$FilePath' already exists!"
}

PowerShell to create files with content

To create a text file with initial content, use the -value parameter to the New-item cmdlet. You can use the -force switch to overwrite an existing file if it exists and even when the directories in the path do not exist.

New-Item -Path C:\Temp\newfile.txt -Value "Hello World!" -ItemType File -Force
"Hello, World!" | Out-File -FilePath .\greetings.txt
Set-Content -Path .\hello.txt -Value "Hello, World!"

Append to Existing File using PowerShell

Keep in mind that these commands will overwrite any existing files with the same name. If you want to append text to an existing file instead of overwriting it, you can use the Add-Content cmdlet or the Out-File cmdlet with the -Append parameter.

Add-Content -Path .\greetings.txt -Value "How are you today?"

Or you can use the Out-File cmdlet with the -Append parameter like this:

"How are you today?" | Out-File -FilePath .\greetings.txt -Append -Encoding utf8

Here is my other post on creating a log file in PowerShell: How to Create a Log File in PowerShell Script?

:/>  Как зайти в реестр: особенности regedit Windows 10 и где находится

Creating a CSV File in PowerShell

Creating a CSV file in PowerShell is easy and can be done using the Export-Csv cmdlet. The Export-Csv cmdlet exports data from a PowerShell object to a CSV file. Here is an example of how to create a CSV file:

$Data = @( @{ Name = "John"; Age = 30; Gender = "Male" }, @{ Name = "Jane"; Age = 25; Gender = "Female" }
)
$Data | Export-Csv -Path "C:\Temp\NewFile.csv" -NoTypeInformation

Creating a JSON File in PowerShell

Creating a JSON file in PowerShell is easy and can be done using the ConvertTo-Json cmdlet. The ConvertTo-Json cmdlet converts PowerShell objects into a JSON format. Here is an example of how to create a JSON file:

$Data = @( @{ Name = "John"; Age = 30; Gender = "Male" }, @{ Name = "Jane"; Age = 25; Gender = "Female" }
)
$Data | ConvertTo-Json | Out-File -FilePath "C:\Users\UserName\Documents\NewFile.json"

This command creates a JSON file named “NewFile.json” and adds the data to the file.

Checking if a File Already Exists in PowerShell

The Test-Path cmdlet can check if a file already exists in PowerShell. The Test-Path cmdlet tests whether the path to a file exists. Here is an example of how to check if a file already exists:

Test-Path -Path "C:\Users\UserName\Documents\NewFile.txt"

This command checks if a file named “NewFile.txt” exists in the specified path.

Using Redirection Operators

Aside from the New-Item cmdlet, we can create files using redirection operators, which serve as a bridge, linking commands and files. The greater-than sign (>) is one of these operators that allows you to create a file and simultaneously add content.

Here’s an illustrative example:

"Hello, World!" > C:\Temp\Example.txt

This command will create a file named “Example.txt” in the “C:\Temp” folder and add the string “Hello, World!” to it. Similarly, to append text, use the >> operator.

"Hello, World!" >> C:\Temp\Example.txt

Troubleshooting Common Issues with File Creation in PowerShell

Here are some common issues you may encounter when creating files in PowerShell and how to troubleshoot them:

Permission Issues

Typing Errors

You will receive an error message if you make typing errors when creating file paths or names. To resolve this issue, double-check the file path and name for errors.

File Already Exists

If you try to create a file that already exists, you will get an error message. To resolve this issue, you should first use the Test-Path cmdlet. This allows you to check if the file already exists before you proceed to create a new file.

Wrapping up

In this article, we saw how you could use PowerShell to create a file in the file system. We have covered the various PowerShell commands for file creation, creating text files, adding content to text files, creating CSV and JSON files, creating multiple files with PowerShell scripts, tips for efficient file creation, and troubleshooting common issues.

You can use the New-Item cmdlet to create a new file and the Add-Content cmdlet to add content to the file. You can also use the Out-File cmdlet to write the output from the PowerShell script into a file.

With this knowledge, you can now master PowerShell for file creation and automate your tasks with ease.

How to Create Files and Folders with PowerShell?

To create a single file with PowerShell, you can use the New-Item cmdlet. For example, to create a new text file named “example.txt”, you can use the command:
New-Item -ItemType File -Path "C:\path\to\example.txt".
To create a folder, you can use the New-Item cmdlet with the -ItemType parameter set to “Directory”. For example, to create a new folder named “LogFiles”, you can use the command:
New-Item -ItemType Directory -Path "C:\path\to\LogFiles".

How do I create an empty text file in PowerShell?

To create an empty text file in PowerShell, you can use the New-Item command with the -ItemType and -Path parameters:
New-Item -ItemType File -Name "filename.txt".
This will create a new empty text file named “filename.txt” in the current directory.

How do I add text to a file in PowerShell?

To add text to a file using PowerShell, you can use the “Add-Content” cmdlet. Here’s an example of how to write data to a file:
Add-Content -Path "C:\Folder\MyFile.txt" -Value "This is some new text."

How to change file extensions with PowerShell?

To change file extensions using PowerShell, you can use the Rename-Item cmdlet. Here’s an example of how to do it:
Rename-Item -Path "C:\Folder\OriginalFile.txt" -NewName "NewFile.csv"
This renames the file extension of txt files to CSV.

Can I use PowerShell to create a zip file?

To create a zip file using Windows PowerShell, you can use the Compress-Archive cmdlet. Here’s an example of how to do it:
Compress-Archive -Path C:\Folder -DestinationPath C:\Archive.zip
More info: How to zip a file using PowerShell?

How to create a batch file to run a PowerShell script?

To create a batch file to run a PowerShell script, you can use any text editor to write a sequence of PowerShell cmdlets and scripts. After composing your commands, save the file with the .bat extension.
More info: How to Run a Batch File from a PowerShell Script?

How to create multiple copies of a file with different names in PowerShell?

How to create a PS1 file in PowerShell?

To create a PS1 file in PowerShell, you can use any text editor, such as Notepad, Visual Studio Code, or PowerShell ISE. Write the PowerShell script and save the file with the .ps1 extension.