简短的问题
如何"foo 1"
使用echo
命令回显字符串,同时将其输出重定向到文件以便将整个字符串写入文件?
C:\>echo foo 1>foo.txt
C:\>type foo.txt
foo
C:\>xxd -g1 a.txt
0000000: 66 6f 6f 20 0d 0a foo ..
上面的实验表明 only"foo "
被写入文件,因为"1"
命令中的 被解释为重定向操作符的一部分,1>
. 请注意,这echo foo 1 > foo.txt
不是一个解决方案,因为它会"foo 1 "
在字符串中使用不必要的尾随空格写入文件。
长问题
请考虑以下 Windows 批处理脚本。
@echo off
call :log "start script"
call :log "foo"
call :log "end script"
goto :eof
:log
echo %~1>>log.txt
goto :eof
当我执行这个脚本时,它的行为如你所愿,即在log.txt 中写入三行日志。
C:\>foo
C:\>type log.txt
start script
foo
end script
现在考虑以下脚本,其中日志的第二行已从 修改"foo"
为"foo 1"
。
@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof
:log
echo %~1>>log.txt
goto :eof
这引起了一些意外。正如您在下面的输出中看到的那样,我们看到的是日志文件"foo"
而不是"foo 1"
日志文件。
C:\Users\pals3\Desktop>foo
C:\Users\pals3\Desktop>type log.txt
start script
foo
end script
@echo off
通过从脚本中删除包含的第一行,然后执行脚本,很容易理解为什么会发生这种情况。
C:\>foo.cmd
C:\>call :log "start script"
C:\>echo start script 1>>log.txt
C:\>goto :eof
C:\>call :log "foo 1"
C:\>echo foo 1>>log.txt
C:\>goto :eof
C:\>call :log "end script"
C:\>echo end script 1>>log.txt
C:\>goto :eof
C:\>goto :eof
从这里可以看出,只要>>log.txt
脚本中有 ,命令解释器就会将其替换为同义语法1>>log.txt
. 这意味着我们的日志命令"foo 1"
现在执行为echo foo 1>>log.txt
,它只是写入"foo"
日志文件。
echo %~1>>log.txt
一个简单的解决方案是将脚本中的语句替换为echo %~1 >>log.txt
.
@echo off
call :log "start script"
call :log "foo 1"
call :log "end script"
goto :eof
:log
echo %~1 >>log.txt
goto :eof
但是,这意味着每一行日志都会以空格字符为后缀,从迂腐的角度来看,这并不理想,并且当人们想要使用 grep 过滤日志文件时会有点混乱。
C:\>foo
C:\>type log.txt
start script
foo 1
end script
C:\>xxd -g1 log.txt
0000000: 73 74 61 72 74 20 73 63 72 69 70 74 20 0d 0a 66 start script ..f
0000010: 6f 6f 20 31 20 0d 0a 65 6e 64 20 73 63 72 69 70 oo 1 ..end scrip
0000020: 74 20 0d 0a
有没有办法编写:log
子例程,以消除我上面提到的惊喜,同时不在每行日志的末尾写一个额外的空间?