Windows komut istemi: Komutun çıktısını ortam değişkenine nasıl alırım?


59

Cmd.exe içinde haftanın gününü içeren bir ortam değişkenine sahip olmak istiyorum.

Bu komutu çalıştırdığımda istediğim sonucu alıyorum.

C:\Users\tisc> powershell (get-date).dayofweek
Friday

Burada sonucu bir ortam değişkeninde depolamaya çalışıyorum.

C:\Users\tisc> set dow = powershell (get-date).dayofweek

Ama onu almaya çalıştığımda istediğim gibi ipi anlamıyorum.

C:\Users\tisc> set dow
DoW=0
dow = powershell (get-date).dayofweek

Amacım, bazı yedekleme komut dosyalarında değişkeni bir toplu iş dosyasında kullanmaktır.

Yanıtlar:


87

Gibi bir şey kullanabilirsiniz:

$env:DOW = "foo"

3
Bunun neden olumsuz olarak işaretlendiğini anlamıyorum, ortam değişkenlerini belirlemek için daha iyisini biliyor musunuz?
Ion Todirel

2
+1 Bu, ihtiyaç duyduğum senaryoda benim için harika çalışıyor. PowerShell -Command $env:Note = 'Elevate'; (New-Object -com 'Shell.Application').ShellExecute('cmd.exe', '/k %*', '', 'runas')
David Ruhmann

14
@IonTodirel Çünkü bu sadece işlem alanında devam eder.
JohnD

Sonunda RAILS_ENV'i powershell olarak nasıl ayarlayacağımı şimdi anlıyorum
wired00

Ve sonra çalıştığından emin olmak için nasıl çıktı elde edersiniz?
CodyBugstein

22

PowerShell, çevresel değişkenleri yönetme kapasitesinden daha fazla olduğundan PowerShell'de her iki komutu da çalıştırmalısınız.

yani:

$dow = (get-date).dayofweek
[Environment]::SetEnvironmentVariable("DOW", $dow, "Machine")

veya

[Environment]::SetEnvironmentVariable("DOW", $dow, "User")

Bu arada, betiğiniz çalışmaz çünkü elde ettiğiniz tek şey PowerShell dönüş kodudur, ürettiği veri değil. Çalışmasını sağlamanın bir yolu olabilir, ancak sonuçta sadece uygun bir PowerShell betiği kullanmaktan çok anlamsız.

Tamamlanması için, Microsoft'tan PowerShell ve çevresel değişkenler hakkında güzel bir makale:

Ortam Değişkenleri Yaratma ve Değiştirme

Güncelleme: Bu çözümü sohbette @ syneticon-dj ile birlikte inceledikten sonra, bu yöntemi kullanırken karşılaştığınız sorun, harici değişkenlerde meydana gelen değişiklikleri yansıtmadan önce bir komut isteminin yeniden yüklenmesi gerektiğidir.

Ne yaptığınız hakkında fazla ayrıntı vermediniz, ancak PowerShell'i başlatmanızın tek sebebi buysa, gerçek önerim işleri nasıl yaptığınızı gözden geçirmekten daha fazla olacaktır.

Tüm işleminiz PowerShell kullanarak mı yoksa bunun yerine zamanlanmış görevleri kullanmayı düşündünüz mü? Haftanın gününe göre görevleri zamanlayabilirsiniz.


Toplu iş dosyası her gün çalıştırılacak ve zamanlanmış görevlerden çalıştırılacak. Bunun yerine powershell'de çalışmayı düşünüyorum. Ama güç kabuğunda cmd'den bile daha fazla acemiyim. Ve şimdi basit bir komutla zorluk çekiyorum. Ama bunun hakkında yeni bir soru yapabilirim, belki bu sizin için kolay bir soru :) EDIT: Anladım. Bazı parametrelerle bir programın nasıl çalıştırılacağıydı.
Tim

Ben de PowerShell'de harika değilim ama öğrenmeye değer. Başlangıç ​​için neredeyse her yönden daha iyi, ama aynı zamanda Microsoft'un (ve diğer üreticilerin) hareket etme şekli.
Dan

1
Ayrıca, yukarıda @ Dan'in önerisinin çevre değişkenlerini kalıcı olarak belirlediğine dikkat edin (Makine veya Kullanıcı bağlamında). Üçüncü parametreyi dışarıda bırakırsanız, bunu sadece daha istenen olan mevcut işlem için ayarlayabilirsiniz.
Lundberg Per

20

[Environment]::SetEnvironmentVariableDan 'in önerdiği şekilde ortam değişkenini PowerShell içinden ayarlamanın anlamsız olduğuna inanıyorum , çünkü geçici "işlem" bağlamını seçtiyseniz ya da toplu iş dosyanızın ortamında henüz bulunmazsa, değişkenin içeriğini PowerShell sonlandırıldığında kaybedersiniz Kalıcı "makine" veya "kullanıcı" bağlamını seçtiyseniz - yani, komut dosyanızın tamamı PowerShell'de yazılı değilse, sorunun ilk başta ortaya çıkmayacağı:

C:\Users\myuser> echo %DOW%
%DOW%

C:\Users\myuser> powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

PS C:\Users\myuser> $dow = (get-date).dayofweek
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "User")
PS C:\Users\myuser> [Environment]::SetEnvironmentVariable("DOW", $dow, "Process")
PS C:\Users\myuser> exit

C:\Users\myuser> echo %DOW%
%DOW%

C:\Users\myuser>

forPowerShell komutunuzun çıktısını ayrıştırmak ve bir değişkene koymak için bu komutu bir geçici çözüm olarak kullanabilirsiniz :

  for /F "usebackq tokens=1" %%i in (`powershell ^(get-date^).dayofweek`) do set DOW=%%i

^PowerShell çağrınızda parantez içindeki özel karakterlerden kaçmak için kullanılan şapka karakterlerini not edin .

Bir toplu iş dosyası bağlamında değil, komut satırından test ediyorsanız, %%önceki değişken referanslarını aşağıdakilerle değiştirmeniz gerekir %:

C:\Users\myuser> for /F "usebackq tokens=1" %i in (`powershell ^(get-date^).dayofw
eek`) do set DOW=%i

C:\Users\myuser> set DOW=Friday

C:\Users\myuser>

Hayır, bu yanlış. Aşağıdaki örneğim, herhangi bir toplu iş dosyasından vb. Erişilebilen 'normal' Çevresel değişkenleri belirler.
Dan

Yanıldığına inanıyorum, [Environment]::SetEnvironmentVariable("DOW", $dow, "user")çalışan bir powershell oturumu içinden ayar yapmaya çalıştım, ancak PowerShell sona erdikten sonra üst cmd oturumumda mevcut değildi
the the wabbit

Biçimlendirme bunu mahvetti, ancak $ dow tanımlamamışsınız. Örneğimi bir Powershell betiğinde çalıştırmak, beklendiği gibi normal bir çevresel değişken depolar.
Dan

1
@ BTW: Aşağı yöndeki oyuna aldırış etmiyorum, ancak gösterilen yaklaşımın , sorgulayıcının istediği şeyi açıkça yaptığı açıkça belirtilmelidir , bu yüzden daha şık bir yaklaşım olsa bile, yine de soruna geçerli bir çözüm olacaktır.
Wabbit

1
@ the-wabbit Windows'da normal davranışa benziyor. Genel ortam değişkenlerini güncelleseniz bile, yalnızca güncelleme değişikliği göreceği için başlatılan işlemler . Bir ebeveyn sürecinden bahsettiğiniz için değişiklikten önce başlamış olmalı. Aynı şey SETKomut İstemi'nde de olur . Bir çocuk başlatmayı deneyin cmd.exeve aynı şeyi göreceksiniz. Gördüğünüz davranış içinde .NET sınıfları aracılığıyla ortam değişkenleri güncelleyerek olsa mevcut süreci etkilemez çünkü gerçi PowerShell olduğunu.
jpmc26

4

Eğer bana ve ana komut varsa vardır bir kabuk olarak, sadece .CMD senaryosu gibi içinde PowerShell arsız çağırmayı yapardım:

set DOW=
for /f %%D in ('%SystemRoot%\System32\WindowsPowerShell\V1.0\powershell.exe -NoLogo -NoProfile -Command Write-Host -Object ^(Get-Date^).DayOfWeek;') do set DOW=%%D

PowerShell yürütme politikanızı kontrol etmeniz gerekebilir (Set-ExecutionPolicy cmdlet).


3

Veya bunu eski kabuğun içinde yapmakla evliyseniz, PowerShell'i tamamen atlayın.

% Date% değişkenini kullanın ve günü, verdiği kısaltmadan genişletin (bu, bölgesel tarih formatı ayarlarından etkilenebilir):

C:\> echo %date%
Thu 09/05/2013

Cevaptaki ilk simgeyi alın ve şunun üzerinde genişletin:

C:\> type dayofweek.cmd
@echo off
for /f %%A in ("%date%") do set DAYOFWEEK=%%A
if "%DAYOFWEEK%" == "Mon" set DAYOFWEEK=Monday
if "%DAYOFWEEK%" == "Tue" set DAYOFWEEK=Tuesday
if "%DAYOFWEEK%" == "Wed" set DAYOFWEEK=Wednesday
if "%DAYOFWEEK%" == "Thu" set DAYOFWEEK=Thursday
if "%DAYOFWEEK%" == "Fri" set DAYOFWEEK=Friday
if "%DAYOFWEEK%" == "Sat" set DAYOFWEEK=Saturday
if "%DAYOFWEEK%" == "Sun" set DAYOFWEEK=Sunday
echo.%DAYOFWEEK%
C:\>
C:\> dayofweek
Thursday

1
Windows 10, DOW% DATE% 'de göstermeyecek: H: \> echo% date% 20/03/2019
Raúl Salinas-Monteagudo

1

Aslında, aşağıdakine benzer bir şeyi bir .ps1 dosyasına (örneğin, t.ps1) yerleştirip PowerShell ile bir CMD oturumundan çağırırken -File t.ps1... iyi çalışıyor.

$DateAndTime = (get-date -UFormat "%Y%m%d_%H%M%S")[Environment]::SetEnvironmentVariable("DateAndTime", $DateAndTime, "Machine")

Ancak, t.ps1 betiğinin çağrıldığı CMD oturumu için değil. Yeni bir CMD oturumunda şunları alıyoruz:

D:> echo% DateAndTime% ==> 20120208_123106

Sanırım export T=datebir CMD oturumunda nasıl bir şey yapılacağını bulmalıyız .


1

Toplu iş dosyanızın, o toplu iş dosyasından çalıştırılan bir PowerShell komutu tarafından ayarlanan ortam değişkenlerine erişmesini istiyorsanız, aşağıdaki geçici çözümü kullanabilirsiniz:

PowerShell betiğinizin mysub.bat, "set değişken = değer" satırları içeren bir alt toplu iş dosyası oluşturmasını sağlayın ve bu mysub.bat toplu iş dosyasını ana toplu iş dosyasından PowerShell komutundan hemen sonra çalıştırın.

Alt toplu iş dosyasının UTF-8 kodlama biçiminde oluşturulmaması için varsayılan PowerShell çıktı yöntemleri yerine WriteAllLines yöntemini kullanın.

Örnek

main.bat:

REM main.bat first line
powershell -Command "[System.IO.File]::WriteAllLines(\".\mysub.bat\", \"set VARIABLE=VALUE\");"
.\mysub.bat
echo VARIABLE=%VARIABLE%
REM expected output: VARIABLE=VALUE
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.