Записать вывод цикла в файл в powershell [duplicate]

В следующем примере, который я написал, показано, как

  • обрабатывать асинхронные HTTP-вызовы;
  • Подождать ответа от каждого вызова API;
  • Использовать шаблон promise ;
  • Используйте шаблон Promise.All для объединения нескольких HTTP-вызовов;

Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.

Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist для заданного набора строк запроса:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

Для каждого элемента новый Promise запустит блок - ExecutionBlock, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user и выполняет новый HTTP-вызов в ExecutionProfileBlock асинхронно.

Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all.

NOTE Recent Spotify search API-интерфейсам потребуется указать токен доступа в заголовках запроса:

-H "Authorization: Bearer {your access token}" 

Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:

var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
    log: function(s) {
        document.getElementById("console").innerHTML += s + "
" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // State changes request.onreadystatechange = function() { if (request.readyState === 4) { // Done if (request.status === 200) { // Complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { var url = "https://api.spotify.com/v1/" url += item; console.log( url ) SimpleRequest.call(url, function(result) { if (result) { var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) { return item.owner.href; }) resolve(profileUrls); } else { reject(new Error("call error")); } }) } arr = [ "search?type=playlist&q=%22doom%20metal%22", "search?type=playlist&q=Adele" ] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // Aggregated results console.log("All profiles received " + results.length); //console.log(JSON.stringify(results[0], null, 2)); ///// promiseall again var ExecutionProfileBlock = function(item, index, resolve, reject) { SimpleRequest.call(item, function(result) { if (result) { var obj = JSON.parse(result); resolve({ name: obj.display_name, followers: obj.followers.total, url: obj.href }); } //result }) } //ExecutionProfileBlock promiseAll(results[0], function(item, index, resolve, reject) { //console.log("Making request [" + index + "] " + item) ExecutionProfileBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results, null, 2)); } , function(error) { // Error console.log(error); }) ///// }, function(error) { // Error console.log(error); });

Я подробно рассмотрел это решение здесь .

163
задан Peter Mortensen 12 July 2015 в 22:33
поделиться

4 ответа

Write-Output следует использовать, когда вы хотите отправить данные в линии трубопровода, но не обязательно хотите отображать его на экране. Конвейер, в конце концов, напишет его на out-default, если ничто другое не использует его в первую очередь. Write-Host следует использовать, когда вы хотите сделать обратное. [console]::WriteLine - это то, что Write-Host делает за кулисами.

Запустите этот демонстрационный код и просмотрите результат.

function Test-Output {
    Write-Output "Hello World"
}

function Test-Output2 {
    Write-Host "Hello World" -foreground Green
}

function Receive-Output {
    process { Write-Host $_ -foreground Yellow }
}

#Output piped to another function, not displayed in first.
Test-Output | Receive-Output

#Output not piped to 2nd function, only displayed in first.
Test-Output2 | Receive-Output 

#Pipeline sends to Out-Default at the end.
Test-Output 

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

write-host ("count=" + $count)

BTW - Смотрите это видео Джеффри Сновера, объясняя, как работает трубопровод. Когда я начал изучать PowerShell, я нашел это наиболее полезным объяснением того, как работает конвейер.

232
ответ дан doubleDown 25 August 2018 в 02:05
поделиться

Помимо того, что сказал Энди, есть еще одна разница, которая может быть важна: write-host напрямую записывает на хост и ничего не возвращает, что означает, что вы не можете перенаправить вывод, например, в файл.

---- script a.ps1 ----
write-host "hello"

Теперь запустите в PowerShell:

PS> .\a.ps1 > someFile.txt
hello
PS> type someFile.txt
PS>

Как видно, вы не можете перенаправить их в файл. Это может быть удивительно для тех, кто не осторожен.

Но если вы переключитесь на использование write-output вместо этого, вы получите перенаправление работать как ожидалось.

26
ответ дан KFL 25 August 2018 в 02:05
поделиться

Из моего теста Write-Output и [Console] :: WriteLine () работают намного лучше, чем Write-Host.

В зависимости от того, сколько текста вам нужно выписать, это может быть важно.

Ниже, если результат 5 тестов каждый для Write-Host, Write-Output и [Console] :: WriteLine ().

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

measure-command {$count = 0; while ($count -lt 1000) { Write-Host "hello"; $count++ }}

1312ms
1651ms
1909ms
1685ms
1788ms


measure-command { $count = 0; while ($count -lt 1000) { Write-Output "hello"; $count++ }}

97ms
105ms
94ms
105ms
98ms


measure-command { $count = 0; while ($count -lt 1000) { [console]::WriteLine("hello"); $count++ }}

158ms
105ms
124ms
99ms
95ms
3
ответ дан tom 25 August 2018 в 02:05
поделиться

Вот еще один способ выполнить эквивалент Write-Output. Просто поставьте свою строку в кавычки:

"count=$count"

Вы можете убедиться, что это работает так же, как Write-Output, запустив этот эксперимент:

"blah blah" > out.txt

Write-Output "blah blah" > out.txt

Write-Host "blah blah" > out.txt

Первые два будут выдавать " blah blah "to out.txt, но третий не будет.

" help Write-Output "дает намек на это поведение:

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

В этом случае сама строка «count = $ count "- это объект в конце конвейера и отображается.

13
ответ дан Twisty Impersonator 25 August 2018 в 02:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: