我需要验证用户是否输入了有效的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.
请推荐。
看起来您的输入路径的形式是列表的字符串文字和/或裸词:
您的无效路径示例之一 -
'/tmp/my dir1,/tmp/my dir2'
- 似乎对您的验证施加了不明显的约束:
Verbatim
/tmp/my dir1,/tmp/my dir2
形式上是有效的 single 路径,因为 ,
是文件名中的合法字符。
NUL
(带有代码点 0x0
的字符)在类 Unix 平台上的文件系统路径中无效。因此,下面的解决方案不允许在单个路径中存在逐字
,
- 根据需要进行调整。
以下解决方案使用两步方法:
它首先通过直接调用 [regex]::Match()
API 将路径的列表
解析为它所代表的逐字项。
有关与
[regex]::Match()
一起使用的正则表达式的说明以及对其进行实验的选项,请参阅 此 regex101.com 页面。
注意其限制:为了(相对)简单性,它仅支持使用引号而不是外部引用所使用的嵌入引用(例如,
'/foo/3" of snow'
或 "/foo/3'o clock"
),但也不是 转义 嵌入引用(例如,"/foo/3`" of snow"
或 '/foo/3''o clock'
)
运算符来验证每个项目是否代表绝对 Unix 格式路径。
-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