提问人:Ashar 提问时间:11/12/2023 最后编辑:Ashar 更新时间:11/13/2023 访问量:89
需要 PowerShell 脚本来验证用户输入是否具有有效的 UNIX 路径
need powershell script to validate user input for valid unix path
问:
我需要验证用户是否输入了有效的 unix 路径语法,而不是主机上的实际路径。
可以有单个或多个路径,用逗号或空格分隔,并用单引号、双引号或根本不用引号括起来。
下面的 PowerShell 尝试无法验证上述条件:
- name: Validate Inputs
run: |
$inputPaths = "${{ inputs.source_files }}"
# Check if the input is not empty
if (-not $inputPaths) {
echo "Error: 'paths' input is required."
exit 1
}
# Check syntax of each provided path
$pathsArray = $inputPaths -split ',| '
foreach ($path in $pathsArray) {
if (-not ($path -match "^[a-zA-Z]:\\|\\\\|/'[^'\s].*'$|^[a-zA-Z]:\\|\\\\|/\"[^\"\s].*\"$|^[a-zA-Z]:\\|\\\\|/[^'\s]+$")) {
echo "Error: '$path' is not a valid absolute path syntax."
exit 1
}
}
echo "Inputs have valid syntax.
有效输入包括
/tmp/mydir
'/tmp/my dir1'
"/tmp/my dir2"
/tmp/mydir '/tmp/my dir1' '/tmp/my dir2'
'/tmp/my dir1','/tmp/my dir2'
无效的输入:
'/tmp/my dir1,/tmp/my dir2'
/tmp/my dir1
'/tmp/my dir1
/tmp/my dir1'
我尝试验证报价,但它在有效报价上出错:
$paths = "'/u/marsh/UNX/scripts/testscript/test_maillist.txt' '/pathx with space/file1' '/path,with,commas/file2' ""/double quoted path/file3"" ""/path with space/file4"" 'single quoted path/file5' /pathx with space/file1"
# Split paths by whitespace or comma while preserving paths enclosed in quotes
$splitPaths = $paths -split "(?<=\S)\s+|(?<=\S),"
foreach ($path in $splitPaths) {
# Check if the path is enclosed in single or double quotes
if (-not (($path -like "'*'") -or ($path -like '"*"'))) {
Write-Host "Error: Path '$path' is not enclosed in single or double quotes."
exit 1
}
# Remove leading and trailing quotes
$cleanPath = $path.Trim("'").Trim('"')
Write-Host "Cleaned Path: $cleanPath"
}
错误输出时不应该有:
Cleaned Path: /u/marsh/UNX/scripts/testscript/test_maillist.txt
Error: Path ''/pathx' is not enclosed in single or double quotes.
恳请建议。
答:
2赞
mklement0
11/13/2023
#1
看起来您的输入路径采用字符串文字和/或准字列表的形式:
您的无效路径示例之一 - - 似乎对您的验证施加了不明显的约束:
'/tmp/my dir1,/tmp/my dir2'
Verbatim 在形式上是一个有效的单一路径,因为它是文件名中的合法字符。
/tmp/my dir1,/tmp/my dir2
,
- 从根本上说,正如 tripleee 所指出的,从技术上讲,只有(带码位的字符)在类 Unix 平台上文件系统的路径中是无效的。
NUL
0x0
- 从根本上说,正如 tripleee 所指出的,从技术上讲,只有(带码位的字符)在类 Unix 平台上文件系统的路径中是无效的。
因此,下面的解决方案不允许在单个路径中逐字存在 - 根据需要进行调整。
,
以下解决方案使用两步方法:
它首先通过直接调用
[regex]::Match()
API 将路径列表解析为它所表示的逐字项。有关用于的正则表达式的说明以及试验它的选项,请参阅此 regex101.com 页。
[regex]::Match()
注意它的局限性:为了(相对)简单,它只支持使用外部引号未使用的引号(例如,或)的形式嵌入引号,但不能转义嵌入引号(例如,
或'/foo/3" of snow'
"/foo/3'o clock"
"/foo/3`" of snow"
'/foo/3''o clock'
)
然后,它使用 PowerShell 的
-match
运算符验证每个项目是否表示绝对 Unix 格式路径。- 有关用于的正则表达式的说明以及试验它的选项,请参阅此 regex101.com 页。
-match
- 有关用于的正则表达式的说明以及试验它的选项,请参阅此 regex101.com 页。
# Sample input paths.
@(
# --- valid
'/tmp/mydir'
"'/tmp/my dir1'"
'"/tmp/my dir2"'
"/tmp/mydir '/tmp/my dir1' '/tmp/my dir2'"
"'/tmp/my dir1','/tmp/my dir2'"
# --- invalid
"'/tmp/my dir1,/tmp/my dir2'"
'/tmp/my dir1' # partly valid (1st token)
"'/tmp/my dir1"
"/tmp/my dir1'"
) |
ForEach-Object {
# Parse each string as a comma- or whitespace-separated list composed of
# string literals and/or barewords.
$match = [regex]::Match(
$_,
'^\s*((?:(?<item>[^"''\s,]+)|(?<quote>["''])(?<item>.*?)\<quote>)(?:(?:\s*,?\s*)|$))+$'
)
if (-not $match.Success) {
# Not a well-formed list of string literals and barewords:
# Report the entire string as invalid.
[pscustomobject] @{
Path = $_
Valid = $false
}
}
else {
# List of string literals and barewords, validate each list item.
$match.Groups['item'].Captures.Value |
ForEach-Object {
[pscustomobject] @{
Path = $_
# To allow "," in paths, remove "," from the regex below.
Valid = $_ -match '^/(?:[^/\0,]+/?)*$'
}
}
}
}
输出(请注意,每个输出行代表一个(成功解析的)单个路径):
Path Valid
---- -----
/tmp/mydir True
/tmp/my dir1 True
/tmp/my dir2 True
/tmp/mydir True
/tmp/my dir1 True
/tmp/my dir2 True
/tmp/my dir1 True
/tmp/my dir2 True
/tmp/my dir1,/tmp/my dir2 False
/tmp/my True
dir1 False
'/tmp/my dir1 False
/tmp/my dir1' False
评论
0赞
Ashar
11/13/2023
它有效,但是如果输入路径是变量,您能否建议更改的内容。我是powershell的新手,所以我可能很难调整你的脚本[解决方案]$userinput = "/tmp/mydir '/tmp/my dir1' '/tmp/my dir2'"
0赞
mklement0
11/13/2023
@Ashar:您的示例也适用于上述解决方案:它将字符串值解析为 、 和 ,所有这些都是有效的绝对 Unix 格式路径。这不是你要找的吗?/tmp/mydir
/tmp/my dir1
/tmp/my dir2
0赞
Ashar
11/13/2023
这正是我正在寻找的,但是您可以建议如果将路径分配给这样的变量,那么您将如何在脚本中处理它# Sample input paths. @( .... )
$userinput = "/tmp/mydir '/tmp/my dir1' '/tmp/my dir2'"
0赞
mklement0
11/13/2023
@Ashar:代替上面的整个数组子表达式,提供 (or ) 作为调用的输入,您将看到它按预期处理。@(...)
"/tmp/mydir '/tmp/my dir1' '/tmp/my dir2'"
$userInput
ForEach-Object
1赞
Ashar
11/13/2023
工程!!谢谢
评论
Resolve-Path
Resolve-Path
actual path
/