cmd batch file removing characters fails - powershell

I am trying to write a custom deploy.cmd for our azure web app deployment. I created a test.cmd script to test removing the first and last character of a file path:
"D:\Program Files (x86)\npm\3.10.3\npm.cmd"
The reason is because the powershell script gets upset if it is not quoted, but the cmd file needs it to not be quoted to run correctly. My test script is:
echo off
setlocal enabledelayedexpansion
SET DEPLOYMENT_SOURCE=D:\home\site\wwwroot
SET NPM_CMD="D:\Program Files (x86)\npm\3.10.3\npm.cmd"
echo %NPM_CMD%
set NPM_CMD=%NPM_CMD:~1, -1%
echo %NPM_CMD%
pushd "%DEPLOYMENT_SOURCE%"
call "%NPM_CMD%" cache clean
call "%NPM_CMD%" install
pushd "%DEPLOYMENT_SOURCE%"
This works and npm is called correctly. So I took the:
set NPM_CMD=%NPM_CMD:~1, -1%
line and put it into my main deploy.cmd file:
echo off
setlocal enabledelayedexpansion
:: Setup
:: -----
echo starting deploy.cmd
echo -------------------
echo %*
SET all=%*
SET NPM_GLOBAL=%1
SET NPM_INFO=%2
echo all: %all%
echo NPM_GLOBAL: %NPM_GLOBAL%
echo NPM_INFO: %NPM_INFO%
SET DEPLOYMENT_SOURCE=D:\home\site\wwwroot
if NPM_GLOBAL=="True" (
REM install specific version of NPM
echo installing specific version of NPM # %NPM_INFO%
npm install -g npm#%NPM_INFO%
%NPM_CMD%=npm
) else (
SET NPM_CMD=%NPM_INFO%
set NPM_CMD=%NPM_CMD:~1, -1%
echo %NPM_CMD%
echo NPM_CMD set to %NPM_CMD%
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo Handling node.js deployment.
echo %DEPLOYMENT_SOURCE%
ECHO %DEPLOYMENT_SOURCE%\package.json
echo Install npm packages
IF EXIST "%DEPLOYMENT_SOURCE%\package.json" (
pushd "%DEPLOYMENT_SOURCE%"
echo Cleaning NPM cache.
call "%NPM_CMD%" cache clean
call "%NPM_CMD%" install
IF !ERRORLEVEL! NEQ 0 goto error
popd
)
This will give the following output:
PS D:\home\site\wwwroot> .\deploy.cmd False "D:\Program Files (x86)\npm\3.10.3\npm.cmd"
D:\home\site\wwwroot>echo off
starting deploy.cmd
-------------------
False "D:\Program Files (x86)\npm\3.10.3\npm.cmd"
all: False "D:\Program Files (x86)\npm\3.10.3\npm.cmd"
NPM_GLOBAL: False
NPM_INFO: "D:\Program Files (x86)\npm\3.10.3\npm.cmd"
ECHO is off.
NPM_CMD set to
'"~1, -1"' is not recognized as an internal or external command,
operable program or batch file.
Handling node.js deployment.
D:\home\site\wwwroot
D:\home\site\wwwroot\package.json
Install npm packages
Cleaning NPM cache.
PS D:\home\site\wwwroot> '"~1, -1"' is not recognized as an internal or external command,
operable program or batch file.
The system cannot find the batch label specified - error
I do not understand why it doesn't know how to remove the first and last character and why it errors. I can't see anything else wrong with the file.

Do not look after stripping surrounding quotes. Instead, define variables without surrounding double quotes as follows:
SET "DEPLOYMENT_SOURCE=D:\home\site\wwwroot"
SET "NPM_CMD=D:\Program Files (x86)\npm\3.10.3\npm.cmd"
and then use them surrounded in double quotes if necessary as follows:
echo %NPM_CMD%
pushd "%DEPLOYMENT_SOURCE%"
call "%NPM_CMD%" cache clean
call "%NPM_CMD%" install
To apply above to your main deploy.cmd file, read in call /?
…
In addition, expansion of batch script argument references (%0, %1,
etc.) have been changed as follows:
%* in a batch script refers to all the arguments (e.g. %1 %2 %3 %4 %5 ...)
Substitution of batch parameters (%n) has been enhanced. You can
now use the following optional syntax:
%~1 - expands %1 removing any surrounding quotes (")
%~f1 - expands %1 to a fully qualified path name
%~d1 - expands %1 to a drive letter only
%~p1 - expands %1 to a path only
Press any key to continue . . .
and apply it when necessary:
echo starting deploy.cmd
echo -------------------
echo %*
SET all=%*
SET "NPM_GLOBAL=%1" 1st parameter is not in double quotes already
SET "NPM_INFO=%~2" 2nd parameter is stripped of surrounding double quotes
Moreover, you need to apply delayed expansion using !variable! instead of %variable% for instance as follows:
(
SET "NPM_CMD=%NPM_INFO%"
rem not necessary now set "NPM_CMD=!NPM_CMD:~1, -1!"
echo !NPM_CMD!
echo NPM_CMD set to !NPM_CMD!
)

To remove quotes around a referenced string, insert a tilde (~) before the parameter number.
%1 to %~1
Changing the start of your batch file to this;
echo starting deploy.cmd
echo -------------------
echo %*
SET all=%*
SET NPM_GLOBAL=%~1
SET NPM_INFO=%~2

Related

Automating the process of importing project into eclipse workspace using command line interface not working as expected

I have command line argument for importing existing project into eclipse work space. But as soon as I try to execute it using windows batch file eclipse opens and starts loading and closes immediately. Here is the code that I am trying to run.
ECHO on
PUSHD
SET ECLPSE=%cd%
SET WORKSPACE=%~dp0
POPD
SET PATH=%PATH%;%ECLPSE%\bin;
RD /s /q %ECLPSE%\configuration\org.eclipse.equinox.app > Nul
RD /s /q %ECLPSE%\configuration\org.eclipse.osgi > Nul
RD /s /q %ECLPSE%\configuration\org.eclipse.update > Nul
START /B %ECLPSE%\bin\tresos_gui.exe -Dmsg1085=false -data %WORKSPACE% %*
START /B %ECLPSE%\bin\tresos_gui.exe importProject -c C:\Jenkins\jobs
This is the syntax for importing a project into the workspace.
tresos_cmd.bat [<system_property>...] [-data <workspace>]
importProject [-c] <project path>...
Can someone please help me with this. I would really appreciate it. I have even combined last two statements in one line and tried executing it but it is of no use. My main aim is to automate the process of importing project into eclipse workspace so that software can be built using jenkins.
All folder paths containing %ECLPSE% or %WORKSPACE% should be enclosed in double quotes in case of %cd% and/or %~dp0 expand to a folder path with a space character or one of the characters &()[]{}^=;!'+,`~.
I did not really understand what is the goal of the batch file and what tresos_gui.exe is for.
However, here is an improved and commented batch file.
#echo off
setlocal EnableExtensions
rem Path of current directory hold in environment variable CD usually does
rem not end with a backslash (directory separator on Windows). But if the
rem current directory is the root directory of a drive, the directory path
rem ends with a backslash. Assign current directory path to environment
rem variable ECLPSE (strange name) always without a trailing backslash.
if not "%CD:~-1%" == "\" ( set "ECLPSE=%CD%" ) else ( set "ECLPSE=%CD:~0,-1%" )
rem Path of batch file always ends with a backslash, but should be assigned
rem to environment variable WORKSPACE always without a trailing backslash.
set "WORKSPACE=%~dp0"
set "WORKSPACE=%WORKSPACE:~0,-1%"
rem The environment variable PATH can end with a folder path or with a
rem semicolon after last folder path. The subdirectory BIN in current
rem directory should be appended with an additional semicolon only if
rem environment variable PATH does not already end with a semicolon.
if "%PATH:~-1%" == ";" ( set "PATH=%PATH%%ECLPSE%\bin" ) else ( set "PATH=%PATH%;%ECLPSE%\bin" )
rem Command RD does not print any message on success. It prints only an error
rem message to handle STDERR if the directory tree could not be removed.
rd /Q /S "%ECLPSE%\configuration\org.eclipse.equinox.app" 2>nul
rd /Q /S "%ECLPSE%\configuration\org.eclipse.osgi" 2>nul
rd /Q /S "%ECLPSE%\configuration\org.eclipse.update" 2>nul
rem Command START interprets first double quoted string as title for the
rem command process window. Therefore specify as first parameter just ""
rem which is an empty title string.
rem The start of tresos_gui.exe is done for some unknown reason in a separate
rem process in background. Hold execution of batch file until this separate
rem process terminated itself before running tresos_gui.exe a second time
rem to import the project and best wait again until this process terminated.
start "" /WAIT /B "%ECLPSE%\bin\tresos_gui.exe" -Dmsg1085=false -data "%WORKSPACE%" %*
start "" /WAIT /B "%ECLPSE%\bin\tresos_gui.exe" importProject -c C:\Jenkins\jobs
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %*
cmd /? ... explains with last paragraph on last help page when double quotes are required.
echo /?
endlocal /?
if /?
rd /?
rem /?
setlocal /?
start /?
And read also the Microsoft TechNet article Using command redirection operators for an explanation of 2>nul.

Loop through each line of text file and run command against each

I am trying to adjust some code which is shown below and hitting walls.
The commandline appears as:
cmd.exe /U /C "C:\Program Files\StorageCraft\ShadowProtect\VerifyImages.cmd <PathOfDirectoryWhichContainsImageFiles> <PathToOutputLogFile>
The code basically runs an image verify command against all md5 files in a directory. The problem is that some directories have >200 md5 files and I only want to verify the files created in the last 24 hrs.
I have been able to create a list of the files created in the last 24hrs and output to a text file using a powershell command.
Is it possible to adjust the script below so that it reads the text file line by line and runs the VERIFY_SUB against each? I have tried using the FOR /F command with little luck to this point.
Thanks in advance.
REM *** START OF MAIN ROUTINE ***
SETLOCAL
PUSHD
CD /D %~dp0
REM Strip the outer quotes off of the directory parameter
SET PARAM_DIR=%1
SET PARAM_DIR=###%PARAM_DIR%###
SET PARAM_DIR=%PARAM_DIR:"###=%
SET PARAM_DIR=%PARAM_DIR:###"=%
SET PARAM_DIR=%PARAM_DIR:###=%
REM Strip the outer quotes off of the output log file parameter
SET PARAM_OUTPUT_FILE=%2
SET PARAM_OUTPUT_FILE=###%PARAM_OUTPUT_FILE%###
SET PARAM_OUTPUT_FILE=%PARAM_OUTPUT_FILE:"###=%
SET PARAM_OUTPUT_FILE=%PARAM_OUTPUT_FILE:###"=%
SET PARAM_OUTPUT_FILE=%PARAM_OUTPUT_FILE:###=%
FOR %%A IN ("%PARAM_DIR%\*.md5") DO (call :VERIFY_SUB "%%A" "%PARAM_OUTPUT_FILE%")
POPD
ENDLOCAL
GOTO :EOF
REM *** END OF MAIN ROUTINE ***
:VERIFY_SUB
#ECHO VERIFYING MD5 FILE %1
#ECHO VERIFYING MD5 FILE %1 >> %2
image.exe v %1 >> %2
#ECHO. >> %2
#ECHO. >> %2
#ECHO. >> %2
GOTO :EOF

Calling Date Modified in CMD

Basically just attempting to create a very basic program that will display the last modified date of a file on our server. Problem is I have no idea how to write it. This is what I attempted
cd \\Server\Folder
msg dir
I also ran into the problem "CMD Does not support UNC Paths as Current Directories" when I tried to change the CD to our servers directory.
What I would like it to do is display in a dialog box the modified date of a "Text.txt" located on our server \\Server\Folder
Any and all help is appreciated
Next .bat script should work:
set "_folder=\\Server\Folder"
set "_filename=Text.txt"
set "_filedatetime=N/A"
pushd %_folder%
for %%G in (%_filename%) do (
rem echo %%~tG %%~fG
if not "%%~tG"=="" set "_filedatetime=%%~tG"
)
popd
echo file %_folder%\%_filename% date and time: %_filedatetime%
Note there is no dialog box in pure cmd command line interpreter, try set /P.
Resources:
SET: Display, set, or remove CMD environment variables
PUSHD, POPD: and UNC Network paths
FOR commands
~ Parameter Extensions

Wrapping Applications with a .bat Script

I recently decided to start using Google's command-line JavaScript compiler (Closure Compiler) to minify JavaScript in my web application. Unfortunately, the compiler is written in Java so the command I have to type to use the compiler is somewhat cumbersome:
java -jar compiler.jar --js hello.js --js_output_file hello-compiled.js
What would be the simplest way for me to wrap this in .bat file that would allow me to simply type closure hello.js hello-compiled.js, while still allowing me to use closure's other command line flags such as --warning-level and --help?
:Start
#echo off
if "%1"=="" Echo Error - input and output parameters were not specified.&goto End
if "%2"=="" Echo Error - output parameter was not specified.&goto End
if not exist %1 Echo Error - input file does not exist.&goto End
set infile=%1
set outfile=%2
set "params="
:Loop
if "%3"=="" goto Continue
set params=%params% %3
shift
goto Loop
:Continue
java -jar compiler.jar --js %infile% --js_output_file %outfile% %params%
set "infile="
set "outfile="
set "params="
:End
I don't know how automated you want this to be, but this will prompt you for your script, your compiled output file, and if you want any extra parameters.
Easily editable if you want more options.
#echo off
set /p script=Script file:
set /p compiled=Compiled script:
set /p params=Enter any extra params (leave blank if none):
if defined params (
java -jar compiler.jar --js %script% --js_output_file %compiled% %params%
) else (
java -jar compiler.jar --js %script% --js_output_file %compiled%
)
echo Done
pause >nul

How to check in command-line if a given file or directory is locked (used by any process)?

I need to know that before any attempt to do anything with such file.
Not sure about locked directories (does Windows have that?)
But detecting if a file is being written to by another process is not difficult.
#echo off
2>nul (
>>test.txt echo off
) && (echo file is not locked) || (echo file is locked)
I use the following test script from another window to place a lock on the file.
(
>&2 pause
) >> test.txt
When I run the 2nd script from one window and then run the 1st script from a second window, I get my "locked" message. Once I press <Enter> in the 1st window, I get the "unlocked" message if I rerun the 1st script.
Explanation
Whenever the output of a command is redirected to a file, the file of course must be opened for write access. The Windows CMD session will attempt to open the file, even if the command does not produce any output.
The >> redirection operator opens the file in append mode.
So >>test.txt echo off will attempt to open the file, it writes nothing to the file (assuming echo is already off), and then it closes the file. The file is not modified in any way.
Most processes lock a file whenever they open a file for write access. (There are OS system calls that allow opening a file for writing in a shared mode, but that is not the default). So if another process already has "test.txt" locked for writing, then the redirection will fail with the following error message sent to stderr - "The process cannot access the file because it is being used by another process.". Also an error code will be generated upon redirection failure. If the command and the redirection succeed, then a success code is returned.
Simply adding 2>nul to the command will not prevent the error message because it redirects the error output for the command, not the redirection. That is why I enclose the command in parentheses and then redirect the error output to nul outside of the parens.
So the error message is effectively hidden, but the error code is still propagated outside of the parens. The standard Windows && and || operators are used to detect whether the command inside the parens was successful or failed. Presumably echo off will never fail, so the only possible reason for failure would be the redirection failed. Most likely it fails because of a locking issue, though technically there could be other reasons for failure.
It is a curious "feature" that Windows does not set the %ERRORLEVEL% dynamic variable to an error upon redirection failure unless the || operator is used. (See File redirection in Windows and %errorlevel%). So the || operator must read the returned error code at some low level, not via the %ERRORLEVEL% variable.
Using these techniques to detect redirection failure can be very useful in a batch context. It can be used to establish locks that allow serialization of multiple events in parallel processes. For example, it can enable multiple processes to safely write to the same log file at the "same" time. How do you have shared log files under Windows?
EDIT
Regarding locked folders. I'm not sure how Windows implements this, perhaps with a lock. But if a process has an active directory involving the folder, then the folder cannot be renamed. That can easily be detected using
2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED
EDIT
I have since learned that (call ) (with a space) is a very fast command without side effects that is guaranteed to succeed with ERRORLEVEL set to 0. And (call) (without a space) is a fast command without side effects that is guaranteed to fail with ERRORLEVEL 1.
So I now use the following to check if a file is locked:
2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
In addition to great answer from dbenham, the following form finally help me understand used technique:
( type nul >> file.txt ) 2>nul || echo File is locked!
type nul command gives an empty output and does not affect the current echo setting like echo off command in orginal.
If you want to use if–then–else condition remember of correct order - success statement (&&) is going first and alternate statement (||) is going second:
command && (echo Command is successful) || (echo Command has failed)
If you download and install the Windows Server 2003 Resource Kit Tools there is a utility called oh.exe that will list open file handles for a given file:
http://www.microsoft.com/en-us/download/details.aspx?id=17657
Once you install it, reboot your machine and you'll be able to use the utility. You can see all the options in the Help and Support center as well as by typing oh /? in the command prompt.
(Info from : http://windowsxp.mvps.org/processlock.htm )
Note, the writing of a message stating the file status was less helpful than a batch command that set a return code. For example, return code 1 if file is locked.
#echo off
2>nul (
>>test.tmp echo off
) && (EXIT /B 0) || (EXIT /B 1)
Other answers resulted in side-effects for me. For instance, the following from this answer will cause file watchers to trigger:
COPY /B app.exe+NUL app.exe
And the following from the top answer here would overwrite any changes made to the target file:
2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
On modern version of Windows, you can call into Powershell to accomplish this task with zero side-effects:
powershell -Command "$FileStream = [System.IO.File]::Open('%FILE%', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" && (echo File is not locked) || (echo File is locked)
This will not modify the file or its metadata at all, even when it isn't locked.
Example usage
I use this method in my custom git mergetool script for merging Excel files. The way a git mergetool works is that it waits for the script shell to exit, then checks if the target file was modified, prompting with "XX.yyy seems unchanged. Was the merge successful [y/n]?" if it wasn't. However, Excel (at least the version I'm using) does not spawn a new process for each file it opens. So if Excel is already open, the script will exit immediately, and git will detect no changes to the file, resulting in that prompt.
So I devised the method above, and I use it like below:
REM block until MERGED is closed
:loop
powershell -Command "$FileStream = [System.IO.File]::Open('%MERGED%', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" >NUL 2>NUL || (goto :loop)
Incidentally, dbenham's solution also seems to be an effective way to find out if a process is running. It was the best solution I found for the following application:
start /b "job1.exe >> job1.out"
start /b /wait "job2.exe >> job2.out"
::wait for job1 to finish using dbenham's code to check if job1.out is in use
comparejobs.exe
Just i want to share with you an example of my script based on #dbenham's trick
Description of this script : Check_Locked_Files.bat :
This script can scan and check for locked files on a set of folders that can be modified into the script; for example, i have chosen those set of folders to be scanned :
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
The output result is in HTML format for more readability.
If the file is locked we show it in red color otherwise we show it in green color.
And the whole script is : Check_Locked_Files.bat
#echo off
Rem This source is inspired from here
Rem hxxps://stackoverflow.com/questions/
Rem 10518151/how-to-check-in-command-line-if-a-given-file-or-directory-is-locked-used-by-any?answertab=active#tab-top
Rem Thanks for dbenham for this nice trick ;)
Mode con cols=90 lines=5 & color 9E
Title Scan and Check for Locked Files by Hackoo 2017
set "LogFile=%~dp0%~n0.html"
(
echo ^<html^>
echo ^<title^> Scan and Check for locked files by Hackoo 2017^</title^>
echo ^<body bgcolor^=#ffdfb7^>
echo ^<center^>^<b^>Log Started on %Date% # %Time% by the user : "%username%" on the computer : "%ComputerName%"^</b^>^</center^>
)> "%LogFile%"
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while ....... Scanning for locked files is in progress
echo --------------------------------------------------------------------------
Rem We Play radio just for fun and in order to let the user be patient until the scan ended
Call :Play_DJ_Buzz_Radio
Timeout /T 3 /nobreak>nul
cls
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
#For %%a in (%Folders%) Do (
( echo ^<hr^>^<font color^=DarkOrange^>^<B^>Folder : %%a^</B^>^</font^>^<hr^>) >> "%LogFile%"
#for /f "delims=" %%b in ('Dir /A-D /s /b "%%~a\*.*"') do (
Call :Scanning "%%~nxb"
Call:Check_Locked_File "%%~b" "%LogFile%"
)
)
(
echo ^<hr^>
echo ^<center^>^<b^>Log ended on %Date% # %Time% on the computer : "%ComputerName%"^</b^>^</center^>
echo ^</body^>
echo ^</html^>
)>> "%LogFile%"
Start "" "%LogFile%" & Call :Stop_Radio & exit
::***********************************************************************************
:Check_Locked_File <File> <LogFile>
(
2>nul (
>>%1 (call )
) && ( #echo ^<font color^=green^>file "%~1"^</font^>^<br^>
) || (
#echo ^<font color^=red^>file "%~1" is locked and is in use^</font^>^<br^>
)
)>>%2 2>nul
exit /b
::***********************************************************************************
:Scanning <file>
cls
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while... Scanning for %1
echo --------------------------------------------------------------------------
exit /b
::***********************************************************************************
:Play_DJ_Buzz_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
Set "vbsfile=%temp%\DJBuzzRadio.vbs"
Set "URL=http://www.chocradios.ch/djbuzzradio_windows.mp3.asx"
Call:Play "%URL%" "%vbsfile%"
Start "" "%vbsfile%"
Exit /b
::**************************************************************
:Play
(
echo Play "%~1"
echo Sub Play(URL^)
echo Dim Sound
echo Set Sound = CreateObject("WMPlayer.OCX"^)
echo Sound.URL = URL
echo Sound.settings.volume = 100
echo Sound.Controls.play
echo do while Sound.currentmedia.duration = 0
echo wscript.sleep 100
echo loop
echo wscript.sleep (int(Sound.currentmedia.duration^)+1^)*1000
echo End Sub
)>%~2
exit /b
::**************************************************************
:Stop_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
If Exist "%vbsfile%" Del "%vbsfile%"
::**************************************************************
:: Create the file Running.tmp
ECHO %DATE% > Running.tmp
ECHO %TIME% >> Running.tmp
:: block it and do the work
(
>&2 CALL :Work 30
) >> Running.tmp
:: when the work is finished, delete the file
DEL Running.tmp
GOTO EOF
:: put here the work to be done by the batch file
:Work
ping 127.0.0.1 -n 2 -w 1000 > NUL
ping 127.0.0.1 -n %1 -w 1000 > NUL
:: when the process finishes, the execution go back
:: to the line after the CALL
In case you want to use this in a Cygwin Bash, here are the one-liners:
# To lock a file: (in a different window)
cmd.exe /C "( >&2 pause ) >> test.txt"
#Press any key to continue . . .
# To test if a file is locked (with text)
cmd.exe /C "2>nul ( >>test.txt (call ) ) && (echo ok) || (echo locked)"
#locked
# To test if a file is locked (with POSIX exit code)
cmd.exe /C "2>nul ( >>test.txt (call ) ) && (exit /b 0) || (exit /b 1)"
echo $?
#1
In case of windows network share you can try powershell command:
Get-SmbOpenFile
For example execute on file server command as administrator:
Get-SmbOpenFile | Where-Object -Property Path -match "file.txt"