Powershell -.bat文件中的Concat字符串

ghhaqwfi  于 2023-06-29  发布在  Shell
关注(0)|答案(2)|浏览(173)

对于我的公司,我开发了一个小的.bat脚本,我用它备份Sqlserver数据库,并对生成的备份文件执行一些操作。目前该脚本工作正常,但我需要添加日期的备份文件名。例如,现在我有Bck_DBTest文件,我想Bck_DBTest_yyyy_mm_dd我已经尝试了各种方法,但从来没有能够追加日期的文件名。
你有什么建议或建议如何实现这一目标吗?
先谢谢你了

  • 我的代码:
powershell -Command "Remove-item -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force"
powershell -Command "Remove-item -Path C:\Backup\db_prod\Backup_Tmp.bak -Force"
set date = powershell -Command "Get-Date -Format MM-dd-yyyy"
sqlcmd -S WIN-xxxxxxxxx -i C:\ScriptBackup\DBBck.sql -o executeBackupOut.txt -U usersql -P usersql
powershell -Command "Compress-Archive -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force -DestinationPath C:\Backup\db_temp\Backup_TmpTest_@date.zip"
powershell -Command "Compress-Archive -Path C:\Backup\db_prod\Backup_Tmp.bak -Force -DestinationPath C:\Backup\db_prod\Backup_Tmp_@date.zip"
EXIT
nhhxz33t

nhhxz33t1#

set date = powershell -Command "Get-Date -Format MM-dd-yyyy"

*最好避免设置变量date,因为它是cmd.exe维护的 * 动态 * 变量

  • 除此之外,*cmd.exeSET语句中, 不要用空格包围= *,因为空格将成为变量名和/或值的一部分。
  • 你不能直接将命令的输出赋值给cmd.exe变量,因为你需要一个for /f语句。

C:\Backup\db_temp\Backup_TmpTest_@date.zip

  • 假设变量date是按预期定义的 *,则在调用powershell.exe时,有两种方式引用在cmd.exe中使用SET定义的变量,Windows PowerShell CLI:
  • 或者:依赖cmd.exe的预先 * 字符串插值 * 并在命令行中嵌入%date%
powershell -c "Compress-Archive ... C:\...\Backup_TmpTest_%date%.zip"
  • 或者:更稳健地,在基于-Command-c)的调用中,依赖于cmd.exe中的SET定义的变量在PowerShell中被视为environment variables的事实,使用$env:date(然而,这对 * 动态 * cmd.exe变量 * 不 * 起作用):
powershell -c "Compress-Archive ... C:\...\Backup_TmpTest_$env:date.zip"

考虑到单个PowerShell CLI调用的成本(如下所述),您可以在单个调用中简单地 * 嵌套 * PowerShell命令:

powershell -c "Compress-Archive ... C:\...\Backup_TmpTest_$(Get-Date -Format MM-dd-yyyy).zip"

退一步

每个PowerShell CLI调用都是:

  • 计算量大
  • 在调用之间保持 no 状态。

因此:

  • 或者:将多个呼叫合并为一个 * 单个 * 呼叫
  • 这可能会影响可读性,但有一些方法(需要小心转义)可以将这样的多语句调用分布在多行中(参见this answer)。
  • 或者:将多个PowerShell语句外包给一个 * 脚本文件 *(*.ps1),您可以使用powershell.exe -File调用它。
vnzz0bqm

vnzz0bqm2#

或者:将多个PowerShell语句外包到脚本文件(*.ps1),您可以使用powershell.exe -File调用该脚本文件。
mklement 0的语句意味着需要两个文件,即BATCH文件和PowerShell脚本。但也有一种方法可以将两者组合成Polyglot
将以下代码放入扩展名为CMD的文件中,运行时,它将首先作为BATCH文件执行(运行<##>之间的部分),BATCH将依次调用PowerShell,后者将依次加载和运行文件本身作为PowerShell脚本块。

注:

  • 示例脚本中的大多数PowerShell命令都包含在此脚本中,但用双引号"括起来,因此它们不会执行,而是简单地显示将执行的内容。
  • 此外,反勾号```用于转义最后两行中预先存在的双引号,并进行了轻微的修改,以使$Date变量在字符串中工作。
  • 这意味着您需要删除额外的双引号和反引号以重新激活这些行。
<# :  REM [### https://stackoverflow.com/questions/43882863/strange-redirect-in-batch-powershell-polyglot ###]
@ECHO OFF
    REM [### Ensure extensions enabled ###]
    SETLOCAL ENABLEEXTENSIONS
    REM [### Define environment variable f0 as this file ###]
    SET f0=%~f0
    REM [### Run this file as a PowerShell script block with $PSScriptRoot and $PSCommandPath defined: https://stackoverflow.com/a/67517934/4190564 ###]
    PowerShell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([System.Management.Automation.Language.Parser]::ParseInput((get-content -raw $Env:f0), $Env:f0, [ref]$null, [ref]$null)).GetScriptBlock()"
GOTO :EOF
#>
"Remove-item -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force"
"Remove-item -Path C:\Backup\db_prod\Backup_Tmp.bak -Force"
$Date = Get-Date -Format MM-dd-yyyy
"sqlcmd -S WIN-xxxxxxxxx -i C:\ScriptBackup\DBBck.sql -o executeBackupOut.txt -U usersql -P usersql"
"Compress-Archive -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force -DestinationPath `"C:\Backup\db_temp\Backup_TmpTest_$Date.zip`""
"Compress-Archive -Path C:\Backup\db_prod\Backup_Tmp.bak -Force -DestinationPath `"C:\Backup\db_prod\Backup_Tmp_$Date.zip`""

结果是以下文本行,它们表示如果删除额外的双引号和反引号,将执行的操作:

Remove-item -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force
Remove-item -Path C:\Backup\db_prod\Backup_Tmp.bak -Force
sqlcmd -S WIN-xxxxxxxxx -i C:\ScriptBackup\DBBck.sql -o executeBackupOut.txt -U usersql -P usersql
Compress-Archive -Path C:\Backup\db_temp\Backup_TmpTest.bak -Force -DestinationPath "C:\Backup\db_temp\Backup_TmpTest_06-08-2023.zip"
Compress-Archive -Path C:\Backup\db_prod\Backup_Tmp.bak -Force -DestinationPath "C:\Backup\db_prod\Backup_Tmp_06-08-2023.zip"

相关问题