Замена переменных powershell не работает

Извините, если глупый вопрос, но я совсем новичок в ps..

Запуск Curl таким образом работает правильно (mailgun отправляет электронное письмо с вложением):

 curl -s --user 'api:***' `
   https://api.eu.mailgun.net/v3/***.com/messages `
   -F from='Builder <[email protected]>' `
   -F [email protected] `
   -F subject='Build failed!!!' `
   -F text='Your build has been failed.' -F attachment='1.txt'

Теперь пытаюсь добавить замену переменной:

 $attstr = "-F attachment='1.txt'"
 curl -s --user 'api:***' `
   https://api.eu.mailgun.net/v3/***.com/messages `
   -F from='Builder <[email protected]>' `
   -F [email protected] `
   -F subject='Build failed!!!' `
   -F text='Your build has been failed.' $attstr

Похоже, переменная игнорируется (получение почты без вложения)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Команда, которую вы на самом деле выполняете:

curl -s --user api:*** `
    https://api.eu.mailgun.net/v3/***.com/messages
    ... etc... `
    -F text='Your build has been failed.' `
    "-F attachment='1.txt'"

Обратите внимание на двойные кавычки вокруг -F attachment='1.txt' — я не знаю, как это интерпретируется в Curl, но он рассматривает содержимое переменной как строковые данные, а не как аргументы команды.

брызги

Если вы хотите, чтобы отдельные части вашей строковой переменной передавались как отдельные аргументы, попробуйте вместо этого разбить их как массив:

$cmdargs = @( "-F", "attachment='1.txt'" )

curl -s --user api:*** `
    https://api.eu.mailgun.net/v3/***.com/messages
    ... etc... `
    -F text='Your build has been failed.' `
    @cmdargs

который выполнит:

curl -s --user api:*** `
    https://api.eu.mailgun.net/v3/***.com/messages
    ... etc... `
    -F text='Your build has been failed.' `
    -F attachment='1.txt'

без окружающих кавычек.

утилита echoargs

Хороший способ диагностировать такого рода проблемы с анализом аргументов — использовать утилиту echoargs.exe с теми же аргументами, что и исходная команда (например, curl ...), и посмотреть, что она выводит на консоль...

PS> $attstr = "-F attachment='1.txt'"

PS> c:\src\so\echoargs.exe -s --user 'api:***' `
>>    https://api.eu.mailgun.net/v3/***.com/messages `
>>    -F from='Builder <[email protected]>' `
>>    -F [email protected] `
>>    -F subject='Build failed!!!' `
>>    -F text='Your build has been failed.' `
>>    $attstr
Arg 0 is <-s>
Arg 1 is <--user>
Arg 2 is <api:***>
Arg 3 is <https://api.eu.mailgun.net/v3/***.com/messages>
Arg 4 is <-F>
Arg 5 is <from=Builder <[email protected]>>
Arg 6 is <-F>
Arg 7 is <[email protected]>
Arg 8 is <-F>
Arg 9 is <subject=Build failed!!!>
Arg 10 is <-F>
Arg 11 is <text=Your build has been failed.>
Arg 12 is <-F attachment='1.txt'>

Command line:
"C:\src\so\echoargs.exe" -s --user api:*** https://api.eu.mailgun.net/v3/***.com/messages -F "from=Builder <[email protected]>" -F [email protected] -F "subject=Build failed!!!" -F "text=Your build has been failed." "-F attachment='1.txt'"

(прокрутите до конца строки, чтобы увидеть значение переменной в двойных кавычках).

Вы можете загрузить готовый двоичный файл echoargs.exe из разных мест (убедитесь, что вы доверяете тому, который используете), или исходный код доступен для самостоятельной компиляции (одну версию см. в этом GitHub gist https://gist.github.com). /pohatu/80b2b01492b0a22e874e).


Дополнительная информация

В моем первоначальном ответе предлагалось использовать curl ... $cmdargs вместо разделения с помощью curl ... @cmdargs - @MathiasR.Jessen правильно указывает, что явное разделение переменной является предпочтительным подходом.

В дополнительном комментарии @mklement0 говорится:

сплаттинг на основе массива неявно применяется при вызове внешних программ

поэтому curl ... $cmdargs логически эквивалентен curl ... $cmdargs, когда $cmdargs представляет собой массив, но чтобы прояснить намерение, вероятно, лучше придерживаться curl ... @cmdargs.

Ух ты. Echoargs... Я пытался найти что-то подобное. Поиграюсь и обновлю

Eduard Dubilyer 15.07.2024 15:06

Это очень простая, но эффективная утилита. Есть составленный на лету список, который я использовал несколько раз, чтобы убедиться, что я доверяю exe-файлу, которому звоню — см. gist.github.com/pohatu/80b2b01492b0a22e874e — никакой принадлежности, просто предпочитаю видеть чем я занимаюсь :-). (обратите внимание: кажется, что он компилируется только в Windows PowerShell, но exe-файл можно нормально вызвать из PowerShell (Core) 7.x)

mclayton 15.07.2024 15:07

А что, если мне нужно динамически создать строку args? Могу ли я добавлять аргументы один за другим в эту структуру данных? Например, у меня есть массив 1.txt, 2.txt, 3.txt, и я хочу перебрать его и построить @("-F", "attachment='1.txt'", "-F", " Attachment='2.txt'", "-F", "attachment='1.txt'") ?

Eduard Dubilyer 15.07.2024 15:15

Вы можете построить массив динамически: $cmdArgs = @(); if ( $something ) { $cmdArgs += @("-F" , "attachment='1.txt'") } (хотя обратите внимание на общепринятое мнение, что из соображений производительности следует избегать оператора «присваивания путем сложения» += для добавления к массивам).

mclayton 15.07.2024 15:19

работает как шарм. Большое спасибо @mclayton. Принятие

Eduard Dubilyer 15.07.2024 15:27

@mclayton Думаю, ты хочешь @cmdArgs здесь

Mathias R. Jessen 15.07.2024 15:29

@MathiasR.Jessen - возможно, но эмпирически echoargs ... $cmdArgs, похоже, здесь тоже работает (по крайней мере, дает тот же результат, что и echoargs ... @cmdargs в команде ^^^). Не уверен, что $cmdargs и @cmdargs могут работать одинаково для собственных команд с переменными строкового массива... (хотя для хеш-таблиц они определенно работают по-разному)

mclayton 15.07.2024 15:46

@MathiasR.Jessen - добавлено обновление для уточнения

mclayton 15.07.2024 15:54

@mclayton Извините, я не совсем ясно выразился в своем предыдущем сообщении: когда вы используете $cmdArgs для передачи массива аргументов, используйте @cmdArgs, чтобы PowerShell передавал их как отдельные строковые значения.

Mathias R. Jessen 15.07.2024 15:56

@MathiasR.Jessen - np. echoargs ... $cmdargs, похоже, передает значения в качестве отдельных аргументов для простого случая, когда $cmdargs представляет собой массив строк (echoargs ... $cmdargs дает Arg 12 is <-F> Arg 13 is <attachment='1.txt'> и -F attachment='1.txt' без кавычек в командной строке), но вы правы, что разметка, вероятно, более правильна. Я посмотрю на переработку ответа позже сегодня...

mclayton 15.07.2024 16:05

Модуль Pscx не обновлялся уже 6,5 лет. Все ли хорошо с PowerShell Core?

lit 15.07.2024 17:48

Другими словами: в сопоставлении «vs» команды идентичны, но только первый вывод выглядит правильно.

mklement0 16.07.2024 00:51

@MathiasR.Jessen - я переработал ответ, чтобы использовать явное разделение - на основе комментария @mklement0, curl ... $cmdaergs эквивалентно curl ... @cmdargs *для переменных со значением массива, но явное разделение делает намерение намного яснее - спасибо за предложения :-)...

mclayton 16.07.2024 11:05

@mklement0 - я отредактировал ответ - я в основном поспешил с разделом «обновление» и запутался - сравнение должно было выглядеть примерно так $cmdargs = @{ "aaa" = "bbb" }; echoargs $cmdargs -> "echoargs.exe" System.Collections.Hashtable, но сейчас я удалил весь этот раздел, так как он был лишним и отвлекал: -)...

mclayton 16.07.2024 11:09

Другие вопросы по теме