단일 스크립트를 윈도우즈 배치 및 리눅스 Bash에서 모두 실행하시겠습니까?
Windows(.bat로 처리)와 Linux(Bash를 통해) 모두에서 실행되는 단일 스크립트 파일을 작성할 수 있습니까?
저는 두 가지 기본 구문을 모두 알고 있지만 이해하지 못했습니다.일부 Bash의 모호한 구문이나 일부 Windows 배치 프로세서 결함을 이용할 수 있습니다.
실행할 명령은 다른 스크립트를 실행하기 위해 한 줄만 사용할 수 있습니다.
Windows와 Linux 모두에 대해 단일 응용 프로그램 부팅 명령을 사용하는 것이 동기입니다.
업데이트: 시스템의 "네이티브" 셸 스크립트의 필요성은 올바른 인터프리터 버전을 선택하고, 잘 알려진 특정 환경 변수를 준수해야 한다는 것입니다.CygWin과 같은 추가 환경을 설치하는 것은 바람직하지 않습니다. 저는 "다운로드 및 실행"이라는 개념을 유지하고 싶습니다.
Windows용으로 고려해야 할 유일한 다른 언어는 Windows 스크립팅 호스트 - WSH이며, 이 언어는 기본적으로 98년부터 사전 설정되어 있습니다.
제가 한 일은 cmd의 레이블 구문을 주석 마커로 사용하는 것입니다.레이블 문자, 콜론(:
), )와true
대부분의 POSIX 조개껍질에서. 수 라벨 문자를 GOTO
그리고 나서 당신의 의견을 말합니다.cmd
스크립트가 사용자에게 영향을 미치지 않아야 합니다.cmd
암호를
" 킹은문시뒤퀀에코드줄것붙입다니이해는을자스."다▁after▁"▁sequence니▁the해▁the것"라는 시퀀스 뒤에 코드 입니다.:;
한 줄짜리 , 한을 쓸 도 있습니다.sh
줄걸쳐에의 여러 .cmd
다음과 같은 것이 좋을지도 모릅니다.의 어떤 사용도 잊지 마십시오.$?
다음 대장 이전이어야 합니다.:
:
재정$?
0까지
:; echo "Hi, I’m ${SHELL}."; exit $?
@ECHO OFF
ECHO I'm %COMSPEC%
매우 인위적인 보호의 예$?
:
:; false; ret=$?
:; [ ${ret} = 0 ] || { echo "Program failed with code ${ret}." >&2; exit 1; }
:; exit
ECHO CMD code.
건너뛸 수 있는 다른 아이디어cmd
코드는 그녀의 의사들을 사용하는 것입니다.sh
료합다.cmd
사용되지 않는 문자열로 코드를 지정합니다.cmd
이 구분 둘 다 따옴표로 , 이경유, 우리의구기모분따두다확묶옴니인합였로는지표호가우다니해석자전는합'▁stop▁in▁quoted다to▁(▁make▁we▁is확oc니iter▁hered▁sure인▁delim▁our합▁that▁boths해,▁this다▁case니석,).sh
와 함께 실행할 때 내용에 대해 어떤 종류의 해석을 하는 것으로부터.sh
하고 )로 시작합니다.:
그 록도하록cmd
다음으로 시작하는 다른 줄처럼 건너뜁니다.:
.
:; echo "I am ${SHELL}"
:<<"::CMDLITERAL"
ECHO I am %COMSPEC%
::CMDLITERAL
:; echo "And ${SHELL} is back!"
:; exit
ECHO And back to %COMSPEC%
필요 또는 코딩 스타일에 따라 인터레이스cmd
그리고.sh
코드가 의미가 있을 수도 있고 아닐 수도 있습니다.이러한 인터레이스를 수행하는 한 가지 방법은 hereocs를 사용하는 것입니다.그러나 이는 다음과 같은 기술로 확장될 수 있습니다.
:<<"::CMDLITERAL"
@ECHO OFF
GOTO :CMDSCRIPT
::CMDLITERAL
echo "I can write free-form ${SHELL} now!"
if :; then
echo "This makes conditional constructs so much easier because"
echo "they can now span multiple lines."
fi
exit $?
:CMDSCRIPT
ECHO Welcome to %COMSPEC%
물론, 보편적인 주석은 캐릭터 시퀀스로 수행될 수 있습니다.: #
또는:;#
은 이 때문에 합니다.sh
#
명령 이름이 식별자의 첫 번째 문자가 아닌 경우 이 이름의 일부가 됩니다.예를 들어, 파일을 사용하기 전에 파일의 첫 줄에 범용 주석을 작성할 수 있습니다.GOTO
코드를 분할하는 방법입니다.그러면 독자에게 스크립트가 이렇게 이상하게 작성된 이유를 알릴 수 있습니다.
: # This is a special script which intermixes both sh
: # and cmd code. It is written this way because it is
: # used in system() shell-outs directly in otherwise
: # portable code. See https://stackoverflow.com/questions/17510688
: # for details.
:; echo "This is ${SHELL}"; exit
@ECHO OFF
ECHO This is %COMSPEC%
그러므로, 몇몇 아이디어들과 성취하는 방법들.sh
그리고.cmd
-제가 아는 한 심각한 부작용이 없는 호환 가능한 스크립트(및 없는 스크립트)cmd
산량출'#' is not recognized as an internal or external command, operable program or batch file.
).
편집
Binki의 대답은 거의 완벽하지만 여전히 개선될 수 있습니다.
:<<BATCH
@echo off
echo %PATH%
exit /b
BATCH
echo $PATH
은 다시 사니다합용다를 합니다.:
트릭과 다중 라인 댓글.cmd.exe(최소 윈도우즈 10)는 유닉스 스타일 EOL과 문제 없이 작동하므로 스크립트가 Linux 형식으로 변환되어야 합니다.(여기와 여기에서 이전에도 같은 접근법이 사용된 적이 있습니다.) 비록 쉐방을 사용하면 여전히 중복된 출력이 생성되지만...
다음을 시도할 수 있습니다.
#|| goto :batch_part
echo $PATH
#exiting the bash part
exit
:batch_part
echo %PATH%
아마도 당신은 사용해야 할 것입니다./r/n
유닉스 스타일 대신 새로운 라인으로.은 unix new line으로 ..bat
대본다른 방법은 다음을 만드는 것입니다.#.exe
내 대답과 유사한 방식으로 아무것도 하지 않는 경로의 파일:임시 파일을 사용하지 않고 배치 파일에 VBScript를 포함하고 실행할 수 있습니까?
저는 코멘트를 하고 싶었지만, 지금은 답변만 추가할 수 있습니다.
주어진 기술들은 훌륭하고 저도 그것들을 사용합니다.
줄 바꿈이. 즉, 두 종 의 즉 것 어 습 니 렵,/n
와 배시파위그리고서해를트▁for▁the./r/n
창문 부분을 위해서요.대부분의 편집자는 편집 중인 파일의 종류를 추측하여 공통 줄 바꿈 체계를 시행합니다.또한 인터넷을 통해 파일을 전송하는 대부분의 방법(특히 텍스트 또는 스크립트 파일)은 줄 바꿈을 실행하므로 한 가지 줄 바꿈으로 시작하여 다른 줄 바꿈으로 끝날 수 있습니다.줄 바꿈을 가정한 다음 스크립트를 다른 사용자에게 사용하도록 지정한 경우 스크립트가 사용자에게 적합하지 않을 수 있습니다.
다른 문제는 여러 시스템 유형(특히 사용자가 사용할 수 있는 소프트웨어를 제어할 수 없는 경우) 간에 공유되는 네트워크 마운트 파일 시스템(또는 CD)입니다.
줄 은 도스 줄 바꿈을 ./r/n
DOS에서 bash 합니다./r
각 줄의 끝에 주석을 달음으로써 (#
) 할 수 . bash에서는 줄바꿈을 사용할 수 없습니다 왜냐하면/r
깨지게 할 겁니다
이러한 방식으로 스크립트를 사용하는 사용자는 어떤 환경에서든 스크립트가 작동합니다.
저는 휴대용 Makefiles를 만드는 것과 함께 이 방법을 사용합니다.
다음은 위의 답변과 달리 Bash 4 및 Windows 10에서 오류 또는 오류 메시지 없이 작동합니다.로 합니다. "what.cmd"로 지정합니다.chmod +x
할 수 있도록 줄 끝단( line)을 .dos2unix
하기
:; if [ -z 0 ]; then
@echo off
goto :WINDOWS
fi
if [ -z "$2" ]; then
echo "usage: $0 <firstArg> <secondArg>"
exit 1
fi
# bash stuff
exit
:WINDOWS
if [%2]==[] (
SETLOCAL enabledelayedexpansion
set usage="usage: %0 <firstArg> <secondArg>"
@echo !usage:"=!
exit /b 1
)
:: windows stuff
변수를 공유할 수 있습니다.
:;SET() { eval $1; }
SET var=value
:;echo $var
:;exit
ECHO %var%
이전 답변들은 거의 모든 옵션을 다루는 것 같고 저에게 많은 도움이 되었습니다.이 답변은 Bash 스크립트와 윈도우즈 CMD 스크립트를 모두 동일한 파일에 포함시켰던 메커니즘을 보여주기 위해 여기에 포함되었습니다.
리눅스 윈도우즈 스크립트.박쥐
echo >/dev/null # >nul & GOTO WINDOWS & rem ^
echo 'Processing for Linux'
# ***********************************************************
# * NOTE: If you modify this content, be sure to remove carriage returns (\r)
# * from the Linux part and leave them in together with the line feeds
# * (\n) for the Windows part. In summary:
# * New lines in Linux: \n
# * New lines in Windows: \r\n
# ***********************************************************
# Do Linux Bash commands here... for example:
StartDir="$(pwd)"
# Then, when all Linux commands are complete, end the script with 'exit'...
exit 0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
:WINDOWS
echo "Processing for Windows"
REM Do Windows CMD commands here... for example:
SET StartDir=%cd%
REM Then, when all Windows commands are complete... the script is done.
요약
Linux의 경우
첫 번째 줄(echo >/dev/null # >nul & GOTO WINDOWS & rem ^
)는 행에 까지 각 exit 0
명령이 실행됩니다.한번만exit 0
이 값에 도달하면 스크립트 실행이 종료되고 아래의 윈도우즈 명령은 무시됩니다.
Windows에서
번째 은 첫번줄다실행니다합음을은째▁the다를 실행합니다.GOTO WINDOWS
명령어, 명령어 바로 뒤에 오는 Linux 명령어를 건너뛰고 다음에서 실행을 계속합니다.:WINDOWS
선을
Windows에서 캐리지 반환 제거
Windows에서 이 파일을 편집할 때부터 Linux 명령에서 캐리지 리턴(\r)을 체계적으로 제거해야 했습니다. 그렇지 않으면 Bash 부분을 실행할 때 비정상적인 결과가 나타납니다.이를 위해 메모장++에서 파일을 열고 다음을 수행했습니다.
끝을 켭니다.
View
>Show Symbol
>Show End of Line
). 캐리지 이 "캐리지 리턴"으로CR
성격.합니다.
Search
>Replace...
하고 확인합니다.Extended (\n, \r, \t, \0, \x...)
선택.형
\r
에 시대에Find what :
필와블아웃을 .Replace with :
필드에 아무것도 없습니다.의 맨 ▁the다▁starting니▁click,합클릭▁file▁at
Replace
돌아올 까지 버튼을 .CR
Linux 맨 위 부분에서 문자가 제거되었습니다. 리턴carriage return)을 바랍니다.CR
입니다. Windows 부분의 문자입니다.
으로 각 한 의 피드로 끝나야 합니다("Linux" "Linux" "Linux" "Linux" "Linux" "Linux" "Linux").LF
) 및 각 및 피드()로CR
LF
).
에서 여러 가지 명령을 실행하는 방법이 있습니다.bash
그리고.cmd
같은 대본으로.
cmd
는 " 으로시행무은시다니합는하다음작"로 합니다.:;
다른 답변에서 언급한 바와 같이또한 현재 행이 명령으로 끝나는 경우 다음 행도 무시됩니다.rem ^
, 럼처.^
는 줄 됩니다.rem
.
만드는 것에 대해서는bash
합니다.cmd
선, 여러 가지 방법이 있습니다.저는 그것을 깨지 않고 하는 몇 가지 방법을 열거했습니다.cmd
명령:
하지 않는 존지하음#
command 되지 않음(명령어)
없는 #
은 용가한명에서 할 수 .cmd
스크립트를 실행하면 다음과 같은 작업을 수행할 수 있습니다.
# 2>nul & echo Hello cmd! & rem ^
echo 'Hello bash!' #
그#
첫머리에 등장하는 것.cmd
makes 라메커이인bash
해당 행을 댓글로 처리합니다.
그#
마지막에 등장하는 인물bash
라인은 코멘트 아웃에 사용됩니다.\r
브라이언 톰셋이 그의 대답에서 지적했듯이, 성격.이거 없으면,bash
파일이 다음을 포함하는 경우 오류가 발생합니다.\r\n
끝, 선끝, 요한경에 의해 cmd
.
를 으로써.# 2>nul
우리는 속고 있습니다.cmd
일부 존재하지 .#
명령을 실행하는 동안 다음 명령을 실행합니다.
다음이 있는 경우 이 솔루션을 사용하지 마십시오.#
은 서사할명령에서 할 수 .PATH
할 수 있는 할 수 할 수 있습니다.cmd
.
용사를 합니다.echo
을 #
에대한특에 있는 cmd
우리는 사용할 수 있습니다.echo
"삽입하도출리디션됩니다렉력이록다니됩▁with▁insert션▁redirect▁it렉ed▁to"를 삽입하는 방향으로 수정됩니다.cmd
는 에대 어령bash
님의 코멘트 영역:
echo >/dev/null # >nul & echo Hello cmd! & rem ^
echo 'Hello bash!' #
#
에 특별한 의미가 없습니다.cmd
그것은 본문의 일부로 다루어집니다.echo
우리가 해야 할 일은 단지 출력물의 방향을 바꾸는 것입니다.echo
명령을 실행하고 그 뒤에 다른 명령을 삽입합니다.
있음 »#.bat
echo >/dev/null # 1>nul 2> #.bat
# & echo Hello cmd! & del #.bat & rem ^
echo 'Hello bash!' #
그echo >/dev/null # 1>nul 2> #.bat
빈 선빈을만니다듭을 .#.bat
파일을 작성하는 동안cmd
기존을 함)#.bat
있는 경우), 사용 중에는 아무것도 하지 않습니다.bash
.
은 이파다사다니됩에서 입니다.cmd
어떤 행#
에 PATH
.
그del #.bat
에 cmd
-특정 코드는 생성된 파일을 삭제합니다.당신은 마지막 날에만 이것을 하면 됩니다.cmd
선을
다음과 같은 경우 이 솔루션 사용 안 함#.bat
파일이 지워지기 때문에 파일이 현재 작업 디렉터리에 있을 수 있습니다.
권장: 여기 문서를 사용하여 무시cmd
는 에대 어령bash
:; echo 'Hello bash!';<<:
echo Hello cmd! & ^
:
다음을 배치합니다.^
마지막에 등장하는 인물cmd
우리는break을 하고, 인라우라브인탈를크출있고고하써, ▁using▁line▁the써를 사용합니다.:
여기서 지정된 구분 기호로서 구분 기호 행 내용은 다음에 영향을 주지 않습니다.cmd
식으로. . . . . . . . . . . . .cmd
▁the다▁after▁execute▁its▁only▁line니▁will실합행 뒤에만 행을 실행합니다.:
되어 라이종습니다었료되인과 .와 동일한 동작을 합니다.bash
.
두 플랫폼 모두에 여러 줄이 있고 블록 끝에서만 실행하려면 다음 작업을 수행할 수 있습니다.
:;( #
:; echo 'Hello' #
:; echo 'bash!' #
:; );<<'here-document delimiter'
(
echo Hello
echo cmd!
) & rem ^
here-document delimiter
한.cmd
와 정확히 일치하는.here-document delimiter
이 해결책은 효과가 있을 것입니다.을 변경할 수 .here-document delimiter
다른 텍스트로.
제시된 모든 솔루션에서 명령은 마지막 줄 뒤에만 실행되므로 두 플랫폼에서 동일한 작업을 수행할 경우 동작이 일관됩니다.
은 이한솔다포파저일합장니다야해에로 파일에 해야 합니다.\r\n
선이 끊어지면, 그렇지 않으면 그들은 작동하지 않을 것입니다.cmd
.
이 기술을 사용하여 실행 가능한 jar 파일을 만듭니다.jar/zip 파일이 zip 헤더에서 시작하기 때문에 이 파일을 실행하기 위한 범용 스크립트를 맨 위에 놓을 수 있습니다.
#!/usr/bin/env sh\n
@ 2>/dev/null # 2>nul & echo off & goto BOF\r\n
:\n
<shell commands go here with \n line endings>
exit\n
\r\n
:BOF\r\n
<cmd commands go here with \r\n line endings>\r\n
exit /B %errorlevel%\r\n
}
다른 플랫폼에서 문제가 발생할 수 있으므로 위에서 설명한 대로 줄 끝을 설정하는 것이 중요합니다.또한 점프 레이블 주위에 적절한 줄 끝이 없는 경우에는 이동 문이 올바르게 작동하지 않습니다.
위의 기술은 제가 현재 사용하는 기술입니다.다음은 자세한 설명이 포함된 오래된 버전입니다.
#!/usr/bin/env sh
@ 2>/dev/null # 2>nul & echo off
:; alias ::=''
:: exec java -jar $JAVA_OPTS "$0" "$@"
:: exit
java -jar %JAVA_OPTS% "%~dpnx0" %*
exit /B
- 첫 번째 줄은 cmd 단위로 반향을 일으키고 sh에 아무것도 인쇄하지 않습니다.는 이유는그 때문입니다.
@
insh는 파이프로 연결되는 오류를 발생시킵니다./dev/null
그리고 나서 댓글이 시작됩니다.에서 cmd에 합니다./dev/null
않기 합니다.#
논평으로서 그 잘못은 에 전가됩니다.nul
그런 다음 반향을 일으킵니다.전체 행 앞에 다음이 있기 때문입니다.@
cd에 - 두 번째는 다음과 같이 정의합니다.
::
하여 sh으로 주석을 합니다.이는 다음과 같은 이점이 있습니다.::
하지 .$?
0
사니다합를용다를"를 합니다.:;
라벨 트릭입니다.라벨' 트릭입니다. - ssh 명령어를 할 수 .
::
됩니다. :: exit
되고 cmd 를 쓸 수 .- 줄만 cmd로 출력되기 가 있습니다.
command not found
당신이 그것이 필요한지 아닌지는 당신 스스로 결정해야 합니다.
일부 Python 패키지 설치 스크립트에 필요했습니다.sh 파일과 bat 파일 사이의 대부분은 동일하지만 오류 처리와 같은 일부는 다릅니다.한 가지 방법은 다음과 같습니다.
common.inc
----------
common statement1
common statement2
그런 다음 bash 스크립트에서 이를 호출합니다.
linux.sh
--------
# do linux specific stuff
...
# call common code
source common.inc
Windows 배치 파일은 다음과 같습니다.
windows.bat
-----------
REM do windows specific things
...
# call common code
call common.inc
대부분의 유닉스 명령에 대해 BusyBox를 사용하는 https://github.com/skanga/bashwin 에서 BashWin 프로젝트를 시도해 보십시오.
Ant 또는 Maven과 같은 플랫폼 독립 빌드 도구는 xml 구문(Java 기반)을 사용합니다.그래서, 당신은 os타입에 상관없이 Ant 또는 Maven에서 모든 스크립트를 다시 작성할 수 있습니다.또는 os 유형을 분석하고 적절한 bat 또는 bash 스크립트를 실행하는 Ant 래퍼 스크립트를 만들 수 있습니다.
언급URL : https://stackoverflow.com/questions/17510688/single-script-to-run-in-both-windows-batch-and-linux-bash
'programing' 카테고리의 다른 글
wpf의 문자열 형식 현지화 문제 (0) | 2023.05.20 |
---|---|
"Microsoft의 이니셜라이저 유형이 표시됩니다.Azure SDK 2.9 설치 후 ccproj 파일을 열 때 'Cct.CctProjectNode'가 예외를 발생했습니다. (0) | 2023.05.20 |
wpf 형식으로 창 닫기 버튼(창 오른쪽 상단 모서리의 빨간색 X 버튼) 이벤트를 포착하는 방법은 무엇입니까? (0) | 2023.05.20 |
모든 파일의 후행 공백을 재귀적으로 제거하는 방법은 무엇입니까? (0) | 2023.05.20 |
jQuery에서 클래스가 여러 개인 요소를 선택하려면 어떻게 해야 합니까? (0) | 2023.05.20 |