将并发的bash代码移植到powershell
我有以下函数编写存储( sync
in unix上):
# Sync Progress Function
function syncStorage {
printq "Writing storage, may take more than 5 minutes."
printq "Although it seems slow, consider this process like flashing an ISO to a USB Drive."
printq "Below is an innacurate indicator of mB left to write. It may decrease hundreds of megabytes in seconds."
# shellcheck disable=SC2016
sync & {
# If the unsynced data (in kB) is greater than 50MB, then show the sync progress
while [[ $(grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+') -gt 5000 ]]; do
SYNC_MB=$(grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+' | awk '{$1/=1024;printf "%.2fMB\n",$1}')
echo -en "\r${SYNC_MB}"
sleep 1
done
}
echo
#watch -n 1 'grep -e Dirty: /proc/meminfo | grep --color=never -o '\''[0-9]\+'\'' | awk '\''{$1/=1024;printf "%.2fMB\n",$1}'\'''
#grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+' | awk '{$1/=1024;printf "%.2fMB\n",$1}'
}
我想将其移植到PowerShell,并到目前为止这样做:
sync & {
# If the unsynced data (in kB) is greater than 50MB, then show the sync progress
# You can replace contents in $(...) with 5001 for testing purposes
while ( $(grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+') -gt 5000 ) {
SYNC_MB=$(grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+' | awk '{$1/=1024;printf "%.2fMB\n",$1}')
echo -en "\r${SYNC_MB}"
sleep 1
}
}
PowerShell接受此语法,但返回:
Id Name PSJobTypeName State HasMoreData Location
-- ---- ------------- ----- ----------- --------
45 Job45 BackgroundJob Running True localhost
# If the unsynced data (in kB) is greater than 50MB, then show the sync progress
while ( 43289423 -gt 5000 ) {
SYNC_MB=$(grep -e Dirty: /proc/meminfo | grep --color=never -o '[0-9]\+' | awk '{$1/=1024;printf "%.2fMB\n",$1}')
echo -en "\r${SYNC_MB}"
sleep 1
}
它不运行该语法代码,它只是将其打印出来。当您用任何值(例如5001以满足WALE循环)替换$(...)时,相同的行为仍然存在。有什么想法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管在表面上相似,但
{...}
在bash vs. powershell中的根本不同:在bash中,这是一种执行直接在呼叫者的范围中。
在PowerShell中,这是一种将语句分组到a 脚本块 ,这是可重复使用的代码单位,要么在 child scope >,通过
&
,调用操作员,或直接通过呼叫者的范围,通过。
, dot-sourcoring oterator 。{
和}
)打印到显示。相比之下,在 shells中,a shell
&
都可以异步启动背景作业,在PowerShell(仅核心)中是隐式等效的,即使用 start-job cmdlet。因此,以下bash呼叫模式:
对应于powershell中的以下内容:
单独,将bash代码转换为powershell :
与bash中不同,powershell中的变量分配存在:
。 /p>
$
Sigil也在那里;例如,$ sync_mb = ...
而不是sync_mb = ...
=
, sissigment operator 。与Bash不同,PowerShell的
-gt
不是独家 numeric :它是一个比单个运算符,也可与 string lhs values一起使用,在这种情况下,它执行词法比较。因此,为了与LHS进行数值比较,该LHS是外部程序的输出,例如
grep
,它总是a string ,您需要将其施放为适当的数字类型,通常[int]
;提供简单的示例:与bash不同,
$(...)
, subexpression操作员 :(...)
,分组操作员echo echo 不参考外部
/bin/echo
实用程序,但是写出
cmdlet,它既不理解> en
options nock 选项,也不了解\
-Escaped逃脱序列,鉴于PowerShell使用`
,所谓的回避角色。虽然您可以通过其完整路径调用
/bin/echo
,但PowerShell方法是使用write-host
cmdlet,如下所示。Alternatively, as you've discovered, PowerShell has a dedicated cmdlet for progress displays,
由于长期存在且高度不幸的错误,PowerShell-至少7.2.2-无法正确通过
“
chars。 >手动\
-escaping ,甚至在 verbatim(single-Quoted)字符串('...'...'...'
) /code>命令。脚本块的儿童分割执行,并假设
同步
是PowerShell script (sync.ps1
)或外部实用程序,将语句放在单独的行上:注意:如果
同步
是PowerShell function ,以上是行不通的,因为后台作业不共享状态状态有了呼叫者,对其功能一无所知(除了通过auto-loading提供的功能模块)。While superficially similar,
{ ... }
in Bash vs. PowerShell are fundamentally different:In Bash, it is a way to group statements to be executed instantly, directly in the caller's scope.
In PowerShell, it is a way to group statements into a script block, which is a reusable unit of code to be executed on demand, either in a child scope, via
&
, the call operator, or directly in the caller's scope, via.
, the dot-sourcing operator.{
and}
) prints to the display .By contrast, in both shells, a post-positional
&
serves to asynchronously launch a background job, which in PowerShell (Core only) is the implicit equivalent of using theStart-Job
cmdlet.Therefore, the following Bash call pattern:
corresponds to the following in PowerShell:
Separately, there are problems with your translation of your Bash code to PowerShell:
Unlike in Bash, variable assignments in PowerShell:
$
sigil there too; e.g.,$SYNC_MB = ...
instead ofSYNC_MB=...
=
, the assignment operator.Unlike in Bash, PowerShell's
-gt
isn't exclusively numeric: it serves as the single greater-than operator that also works with string LHS values, in which case it performs lexical comparison.Therefore, in order to perform numerical comparison with an LHS that is the output from an external program such as
grep
, which is invariably a string, you need to cast it to an appropriate number type, typically[int]
; to provide simple examples:Unlike in Bash,
$(...)
, the subexpression operator is rarely needed outside expandable (double-quoted) string ("..."
):(...)
, the grouping operatorecho
doesn't refer to the external/bin/echo
utility, but is a built-in alias of theWrite-Output
cmdlet, which understands neither the-en
options nor\
-escaped escape sequences, given that PowerShell uses`
, the so-called backtick, as its escape character.While you could call
/bin/echo
via its full path, the PowerShell way is to use theWrite-Host
cmdlet, as shown below.Alternatively, as you've discovered, PowerShell has a dedicated cmdlet for progress displays,
Write-Progress
, but note that its downside is that it can slow the overall operation down noticeably.Due to a long-standing and highly unfortunate bug, PowerShell - up to at least 7.2.2 - doesn't properly pass
"
chars. embedded in external-program arguments, necessitating their manual\
-escaping, even inside verbatim (single-quoted) string ('...'
), such as in yourawk
command.To put it all together, using
&
for child-scoped execution of the script block, and assuming thatsync
is either a PowerShell script (sync.ps1
) or an external utility, placing the statements on separate lines:Note: If
sync
were a PowerShell function, the above wouldn't work, because background jobs do not share state with the caller and know nothing about its functions (except functions provided via auto-loading modules).