พรอมต์คำสั่งของ Windows: ฉันจะรับเอาต์พุตของคำสั่งลงในตัวแปรสภาพแวดล้อมได้อย่างไร


59

ฉันต้องการตัวแปรสภาพแวดล้อมที่มีวันในสัปดาห์ใน cmd.exe

เมื่อฉันเรียกใช้คำสั่งนี้ฉันได้รับผลลัพธ์ที่ต้องการ

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

ที่นี่ฉันพยายามเก็บผลลัพธ์ไว้ในตัวแปรสภาพแวดล้อม

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

แต่เมื่อฉันพยายามที่จะรับมันฉันไม่ได้รับสายตามที่ฉันต้องการ

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

เป้าหมายของฉันคือใช้ตัวแปรในไฟล์แบตช์สำหรับสคริปต์สำรองบางตัว

คำตอบ:


87

คุณสามารถใช้สิ่งที่ชอบ:

$env:DOW = "foo"

3
ฉันไม่เข้าใจว่าทำไมการตั้งค่าสถานะนี้จึงเป็นค่าลบคุณทราบดีกว่าการตั้งค่าตัวแปรสภาพแวดล้อมหรือไม่
ไอออน Todirel

2
+1 สิ่งนี้ใช้งานได้ดีสำหรับฉันในสถานการณ์ที่ฉันต้องการ PowerShell -Command $env:Note = 'Elevate'; (New-Object -com 'Shell.Application').ShellExecute('cmd.exe', '/k %*', '', 'runas')
David Ruhmann

14
@IodTodirel เพราะสิ่งนี้ยังคงอยู่ในพื้นที่กระบวนการเท่านั้น
JohnD

ในที่สุดฉันก็เข้าใจวิธีตั้ง RAILS_ENV ใน powershell
wired00

แล้วคุณจะทำมันออกมาอย่างไรเพื่อให้แน่ใจว่ามันใช้งานได้?
CodyBugstein

22

คุณควรเรียกใช้ทั้งสองคำสั่งใน PowerShell เนื่องจาก PowerShell มีความสามารถในการจัดการตัวแปรสภาพแวดล้อมมากกว่า

เช่น:

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

หรือ

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

โดยวิธีการที่สคริปต์ของคุณไม่ทำงานเพราะสิ่งที่คุณได้รับคือรหัสส่งคืน PowerShell ไม่ใช่ข้อมูลที่ผลิต อาจมีวิธีที่จะทำให้มันใช้งานได้ แต่ท้ายที่สุดก็ไม่มีจุดหมายเมื่อเทียบกับการใช้สคริปต์ PowerShell ที่เหมาะสม

เพื่อความสมบูรณ์นี่เป็นบทความที่ดีจาก Microsoft เกี่ยวกับ PowerShell และตัวแปรด้านสิ่งแวดล้อม:

การสร้างและแก้ไขตัวแปรสภาพแวดล้อม

อัปเดต:เมื่อตรวจทานโซลูชันนี้ด้วย @ syneticon-dj ในการแชทแล้วปัญหาที่คุณเผชิญโดยใช้วิธีนี้คือต้องมีการโหลดพรอมต์คำสั่งใหม่ก่อนที่จะสะท้อนการเปลี่ยนแปลงของตัวแปรสภาพแวดล้อมที่เกิดขึ้นจากภายนอก

คุณยังไม่ได้ให้รายละเอียดมากนักเกี่ยวกับสิ่งที่คุณกำลังทำ แต่ถ้านี่เป็นเหตุผลเดียวที่คุณเปิดตัว PowerShell กว่าคำแนะนำจริงของฉันคือการตรวจสอบว่าคุณกำลังทำอะไรอยู่

กระบวนการทั้งหมดของคุณใช้ PowerShell หรือคุณพิจารณาใช้งานที่กำหนดไว้แทนหรือไม่ คุณสามารถกำหนดเวลางานตามวันในสัปดาห์


ไฟล์แบตช์จะถูกเรียกใช้ทุกวันและเรียกใช้จากงานที่กำหนด ฉันคิดว่าการทำงานใน PowerShell แทน แต่ฉันมือใหม่ยิ่งกว่าใน powerhell กว่า cmd และตอนนี้ฉันมีปัญหากับคำสั่งง่ายๆ แต่ฉันสามารถสร้างคำถามใหม่เกี่ยวกับคำถามนั้นได้อาจเป็นคำถามที่ง่ายสำหรับคุณ :) แก้ไข: ฉันหาคำตอบแล้ว มันเป็นวิธีการเรียกใช้โปรแกรมด้วยพารามิเตอร์บางอย่าง
ทิม

ฉันไม่เก่งใน PowerShell แต่ก็คุ้มค่ากับการเรียนรู้ สำหรับการเริ่มต้นมันแทบจะดีกว่าในทุก ๆ ด้าน แต่มันก็เป็นวิธีที่ Microsoft (และผู้ผลิตรายอื่น) กำลังเคลื่อนไหว
ด่าน

1
นอกจากนี้โปรดทราบว่าคำแนะนำของ @ Dan ด้านบนตั้งค่าตัวแปรสภาพแวดล้อมค่อนข้างถาวร (ทั้งในบริบทของเครื่องจักรหรือผู้ใช้) หากคุณไม่ใช้พารามิเตอร์ที่สามคุณสามารถตั้งค่าเป็นเพียงกระบวนการปัจจุบันซึ่งบางครั้งก็เป็นที่ต้องการมากกว่า
ต่อ Lundberg

20

ผมเชื่อว่าการตั้งค่าตัวแปรสภาพแวดล้อมจากภายใน PowerShell กับ[Environment]::SetEnvironmentVariableการแนะนำโดยแดนจะไม่มีจุดหมายเพราะคุณจะได้ทั้งสูญเสียเนื้อหาของตัวแปรเมื่อสิ้นสุด PowerShell ถ้าคุณเลือกชั่วคราว "ขั้นตอน" บริบทหรือจะไม่ได้ภายในสภาพแวดล้อมของแบทช์ไฟล์ของคุณเลยหากคุณเลือกบริบท "เครื่อง" หรือ "ผู้ใช้" อย่างถาวร - นั่นคือเว้นแต่ว่าสคริปต์ทั้งหมดของคุณจะถูกเขียนใน PowerShell ซึ่งปัญหาจะไม่เกิดขึ้นตั้งแต่แรก:

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>

คุณสามารถใช้forคำสั่งเป็นวิธีแก้ปัญหาเพื่อแยกวิเคราะห์ผลลัพธ์ของคำสั่ง PowerShell ของคุณและวางลงในตัวแปร:

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

บันทึกอักขระคาเร็ตที่^ใช้เพื่อหลีกเลี่ยงอักขระพิเศษวงเล็บภายในการโทร PowerShell ของคุณ

หากคุณกำลังทดสอบจากบรรทัดคำสั่งและไม่อยู่ในบริบทแบตช์ไฟล์คุณจะต้องแทนที่%%ก่อนการอ้างอิงตัวแปรโดย%:

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>

ไม่ถูกต้อง ตัวอย่างด้านล่างของฉัน 'ปกติ' ตัวแปรสิ่งแวดล้อมชุดซึ่งสามารถเข้าถึงได้จากไฟล์ชุดใด ๆ ฯลฯ
แดน

@ แดนฉันเชื่อว่าคุณเข้าใจผิดฉันได้ลองตั้งค่า[Environment]::SetEnvironmentVariable("DOW", $dow, "user")จากภายในเซสชัน PowerShell ที่ทำงานอยู่ แต่มันไม่ได้อยู่ในเซสชั่นผู้ปกครองของฉันเมื่อเลิก PowerShell
the-wabbit

การจัดรูปแบบทำให้เกิดความผิดพลาด แต่คุณยังไม่ได้กำหนด $ dow การใช้ตัวอย่างของฉันในสคริปต์ Powershell เก็บตัวแปรสภาพแวดล้อมตามปกติตามที่คาดไว้
ด่าน

1
@Ban BTW: ฉันไม่รังเกียจการ downvoting แต่ควรสังเกตว่าวิธีการสาธิตแสดงให้เห็นอย่างชัดเจนว่าสิ่งที่ผู้ถามได้ถามดังนั้นแม้ว่าจะมีวิธีการที่หรูหรากว่านี้ก็ยังคงเป็นวิธีการแก้ปัญหาที่ถูกต้อง
the-wabbit

1
@ the-wabbit ฟังดูเหมือนพฤติกรรมปกติใน Windows แม้ว่าคุณจะอัพเดตตัวแปรสภาวะแวดล้อมโกลบอลกระบวนการที่เริ่มต้นตั้งแต่การอัพเดตจะรับรู้การเปลี่ยนแปลง เนื่องจากคุณกำลังพูดถึงกระบวนการหลักจะต้องเริ่มต้นก่อนการเปลี่ยนแปลง สิ่งเดียวกันนี้เกิดขึ้นSETใน Command Prompt ลองเริ่มเด็กcmd.exeแล้วคุณจะเห็นสิ่งเดียวกัน พฤติกรรมที่คุณเห็นใน PowerShell เป็นเพราะการอัปเดตตัวแปรสภาพแวดล้อมผ่านคลาส NET. ไม่ส่งผลกระทบต่อกระบวนการปัจจุบัน
jpmc26

4

ถ้ามันเป็นฉันและสคริปต์ที่ผู้ปกครองมีจะเป็นสคริปต์เปลือกฉันเพียงแค่ต้องการทำภาวนาหน้าด้านของ PowerShell ในสคริปต์ .cmd ที่ชอบ:

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 ของคุณ (Set-ExecutionPolicy cmdlet)


3

หรือถ้าคุณแต่งงานเพื่อทำสิ่งนี้ในกระสุนเก่าให้ข้าม PowerShell โดยสิ้นเชิง

ใช้ตัวแปร% date% และขยายวันจากตัวย่อที่ให้ (อาจมีผลจากการตั้งค่ารูปแบบวันที่ภูมิภาค):

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

คว้าโทเค็นแรกในคำตอบและขยายสิ่งต่อไปนี้:

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%: H: \> echo% วันที่% 20/03/2019
Raúl Salinas-Monteagudo

1

ที่จริงแล้วเมื่อวางบางอย่างเช่นด้านล่างในไฟล์. ps1 (พูดt.ps1) และเรียกมันจากเซสชัน CMD ด้วย PowerShell -File t.ps1... มันทำงานได้ดี

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

แต่ไม่ใช่สำหรับเซสชัน CMD ที่เรียกใช้สคริปต์ t.ps1 ในเซสชั่น CMD ใหม่เราจะได้รับ:

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

ฉันเดาว่าเราต้องหาวิธีที่จะทำอะไรบางอย่างexport T=dateในเซสชั่น CMD


1

หากคุณต้องการให้ไฟล์แบตช์ของคุณเข้าถึงตัวแปรสภาพแวดล้อมที่ตั้งค่าโดยคำสั่ง PowerShell ที่รันจากไฟล์แบตช์นั้นคุณสามารถใช้วิธีแก้ไขปัญหาต่อไปนี้:

ทำให้สคริปต์ PowerShell ของคุณสร้างไฟล์แบตช์ย่อยmysub.batที่มีบรรทัด "set variable = value" และเรียกใช้ไฟล์แบตช์ mysub.bat จากไฟล์แบตช์หลักหลังจากคำสั่ง PowerShell

ใช้เมธอด WriteAllLines แทนวิธีเอาต์พุต PowerShell เริ่มต้นเพื่อไม่ให้สร้างไฟล์แบตช์ย่อยด้วยรูปแบบการเข้ารหัส UTF-8

ตัวอย่าง

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.