尝试将 /f "tokens=*" %%a in ... 转换为SHELL。
尝试将 /f "tokens=*" %%a in ... 转换为SHELL。
我正在尝试将一个BATCH脚本使用这种类似的转换器手册转换为SHELL脚本。(整个BATCH脚本)我已经快要完成了,但我正在努力转换这个FOR循环:
for /f "tokens=*" %%a in ('%adb% shell mkdir /usr/ui/^|find /i "File exists"') do ( if not errorlevel 1 goto :cannot_patch )
我知道for /f
是:
循环命令:对一组文件进行条件执行每个项目的命令。
然而,由于我是SHELL SCRIPT(以及BASH)的新手,我最好的尝试是:
for -f "tokens=*" a in ( '$ADB shell mkdir /usr/ui/^|find /i "File exists"' ); do if [ $? -nq 1 ] then cannot_patch fi done
这不起作用,导致一个Syntax error: Bad for loop variable
。
任何提示、链接或建议都将非常感激。
编辑
我试图理解(\'%adb% shell mkdir /usr/ui/^|find /i \"File exists\"\'
到底是在做什么。
我认为这些是sh命令,但事实证明我错了,find /i
试图
在文件中搜索文本字符串,并显示找到它的所有行。
(https://ss64.com/nt/find.html)
|
是管道操作符,\"File exists\"
应该是mkdir
在尝试创建已经存在的目录时抛出的错误。
所以我认为我可能可以更容易地写这个,但是,/usr/ui/^
中的^
符号是什么作用?它是一个正则表达式吗?
编辑2
看来@glenn_jackman是对的:可能我最好了解代码试图做什么。
所以为了给出更好的上下文,这里是原始批处理程序的一些更多代码:
for /f "tokens=*" %%a in ('%adb% shell mkdir /usr/ui/^|find /i "File exists"') do ( if not errorlevel 1 goto :cannot_patch ) :cannot_patch echo Error: Cannot create directory! echo Patch is already installed or system files exist and might be overwritten. choice /m "Do you want to continue" if errorlevel 2 goto :END goto :continue_patch
据我理解,该代码试图运行adb shell mkdir
命令,如果失败(抛出“文件已存在”错误),它将询问用户是否仍要继续。
所以在这种情况下,我想真正的问题是尝试编写一个在SH中完成相同任务的代码,可能不需要使用for循环。
尽管如此,我还在找出解决办法……
您的循环的一般语法匹配 https://ss64.com/nt/for.html
您还应该阅读 https://ss64.com/nt/errorlevel.html 和 这个SO参考列表/解释错误代码。
从 SO 文章中,FOR /F │ 1 = No data was processed.
但错误级别页面说
IF ERRORLEVEL 1 will return TRUE whether the errorlevel is 1 or 5 or 64
而SO文章还说
if %errorlevel% equ 5 ( echo Can not access the directory, check rights )
显然,^
是CMD转义字符,在这里用于转义作为复合命令的一部分传递的管道字符(我猜...),以便我将其解析为尝试创建目录,检查其是否已经存在并根据需要响应。
我认为在bash中应该这样写:
mkdir /usr/ui/ || cannot_patch
for /f "tokens=*" %%a in ('%adb% shell mkdir /usr/ui/^|find /i "File exists"') do ( if not errorlevel 1 goto :cannot_patch )
运行命令%adb% shell mkdir /usr/ui/
然后在该输出中搜索字符串File exists
。if not errorlevel 1
的意思是“如果%errorlevel%不大于或等于1”,这是一种奇怪而笨拙的方式,只需说if“%errorlevel%” ==“0”
就可以了,这意味着找到了字符串。如果找到了,则脚本跳转到标签:cannot_patch
。
在bash中,处理命令输出的方法是使用$()
而不是for /f
,因此
$(${adb} shell mkdir /usr/ui/ | grep "File exists") && cannot_patch
假设变量adb
已设置,并且您的shell脚本中有一个名为cannot_patch
的函数。
请注意,我答案与Paul Hodge的答案之间的唯一区别是我假设您仍需要调用ADB
。