我已将建议的解决方案输入到记录整个批处理文件的输出。
但仅当我们的批处理脚本不要求管理员访问权限或接受任何用户输入时才有效。
在我的脚本中我获得了管理访问权限并且还有用户输入:
@echo off
:: BatchGotAdmin
::-------------------------------------
REM --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
echo Requesting administrative privileges...
goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"="
echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B
:gotAdmin
pushd "%CD%"
CD /D "%~dp0"
::--------------------------------------
set LOGFILE=batch.log
call :LOG > %LOGFILE%
exit /B
:LOG
REM Set IP address to USB Ethernet
echo "Set IP address to USB Ethernet :"
set /p SystemIP="Enter the System IP address[127.*.*.*]:"
set /p SystemSubnetMask="Enter the System Subnetmark[Default:255.255.255.0]:"
IF [%system_subnetmask%]==[] set /p system_subnetmask=255.255.255.0
set /p SystemGateway="Enter the System Default Gateway[127.*.*.*]:"
echo "Aviliable Ethernet Interface :"
netsh interface show interface
set /p EthernetInterfaceName="Type the Ethernet Interface Name:"
netsh interface ip set address %EthernetInterfaceName% static %SystemIP% %SystemSubnetMask% %SystemGateway%
netsh interface ip set dns %EthernetInterfaceName% static 8.8.8.8
netsh interface ip add dnsserver %EthernetInterfaceName% address=4.2.2.2 index=1
答案1
“如何在批处理脚本中进行准入访问后进行日志记录?”
- 这关联您的问题以多种方式回答了这个问题。
“我已在下面的链接中输入了建议的解决方案,但仅当我们的批处理脚本不要求管理员访问权限时才有效......
- 您的代码需要进行一些更改/编辑,包括使用动态数据库,并会干扰请求管理员权限的机制。”
“...或接受任何用户输入。”
- 代码中的这些操作将接收输入,是在获取管理员权限(通过 VBS)的操作之后,因此如果前一个操作没有发生,则这个操作也不会发生。
无需赘述,您的目标集中在获取批量列出的命令执行日志,但在尝试这样做时,由于使用重定向到日志文件,因此您省略了屏幕的输出,但是,没有意识到屏幕(stdout)不会有任何命令输出,它甚至会瘫痪并等待set /p
命令输入。
这不会真正破坏您正在运行的代码,但它肯定会“挂起”而没有在屏幕上显示任何消息,并且它会停留在那里等待用户/管理员交互继续,而这种情况永远不会发生。
我建议进行以下改变:将注册所需的操作与接收交互/输入所需的操作分开:
@echo off
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" && goto :gotAdmin
echo/Requesting administrative privileges... & goto :UACPrompt
:UACPrompt
set "_params=" & if not "%*" == "" =;(
set "_params=%*"
call set "_params=%%_params:"=%%"
);=
> "%temp%\getadmin.vbs" =;(
echo/Set UAC = CreateObject("Shell.Application"^)
echo/UAC.ShellExecute "%ComSpec%", "/c %~s0 %_params%", "", "runas", 1
);= && "C:\Windows\System32\cscript.exe" //Nologo "%temp%\getadmin.vbs"
>nul 2>&1 del /q "%temp%\getadmin.vbs" & exit /b || goto :eOf
:gotAdmin
cd /d "%~dp0"
set "_LogFile=%temp%\batch.log"
echo/Set IP address to USB Ethernet :
set /p "_SystemIP=Enter the System IP address [127.*.*.*]: "
set /p "_SystemSubnetMask=Enter the System Subnet Mask [Default: 255.255.255.0]: "
if "%_SystemSubnetMask%" == "" set "_System_SubnetMask=255.255.255.0"
set /p "_SystemGateway=Enter the System Default Gateway [127.*.*.*]: "
echo/Aviliable Ethernet Interface:
"C:\Windows\System32\netsh.exe" interface show interface | findstr .
set /p "_EthernetInterfaceName=Type the Ethernet Interface Name: "
:: logging commands after defined in/with admin inputs
:: ----------------------------------------------------
for %%i in (EthernetInterfaceName,SystemIP, SystemSubnetMask, SystemGateway
)do "%ComSpec%" /v:on /e:on /c "echo/%%~i: !_%%~i!"
2>&1 =;(
netsh interface show interface | findstr .
for %%i in (EthernetInterfaceName,SystemIP, SystemSubnetMask, SystemGateway)do "%ComSpec%" /v:on /e:on /c "echo/%%~i: !_%%~i!"
echo\ "C:\Windows\System32\netsh.exe" interface ip set address %_EthernetInterfaceName% static %_SystemIP% %_SystemSubnetMask% %_SystemGateway%
echo\ "C:\Windows\System32\netsh.exe" interface ip set dns %_EthernetInterfaceName% static 8.8.8.8
echo\ "C:\Windows\System32\netsh.exe" interface ip add dnsserver %_EthernetInterfaceName% address=4.2.2.2 index=1
echo\ "C:\Windows\System32\ipconfig.exe" /flushdns
);= >"%_LogFile%"
type "%_LogFile%" | clip
"C:\Windows\System32\timeout.exe" -1
- 为什么?
虽然可以重定向stderr
到stdout
,也可以重定向stderr
和stdout
同时,不可能的是重定向stdin
(set /P
)到stdout
到一个文件并同时stdout
屏幕接收stdin
. 而你的问题正指向这个目标。
指针流
stdin、stdout 和 stderr 全局常量指针是用于输入、输出和错误输出的标准流
stdin Standard input
stderr Standard error
stdout Standard output
Redirection:
stderr <to> Null <use> 2>Nul
stderr <to> stdout <use> 2>&1
stderr <to> File.Log <use> 2>File.Log
stdout <to> Null <use> >Nul
stdout <to> Null <use> 1>Nul
stdout <to> File.Log <use> >File.Log
stdout <to> File.Log <use> 1>File.Log
Redirection stdout and stderr to File.Log:
2>&1 YourCommandHere >File.Log
2>&1 YourCommandHere 1>File.Log
Set IP address to USB Ethernet :
Enter the System IP address [127.*.*.*]: //user input [stdin]
Enter the System Subnet Mask [Default: 255.255.255.0]: //user input [stdin]
Enter the System Default Gateway [127.*.*.*]: //user input [stdin]
Avaliable Ethernet Interface:
Admin State. State Type Interface Name
-------------------------------------------------------------------------
Enable Conected Dedicaed Wi-Fi
Type the Ethernet Interface Name: //user input [stdin]
其他资源:
If /?
Del /?
FindSTR /?
For /?
- 条件执行
- 命令重定向
|
,<
,>
,2>
, ETC。
- Windows 命令解释器如何
cmd.exe
解析脚本