옳은 길
gtk-launch
가능한 경우 실제로 사용해야 합니다. 일반적으로 libgtk-3-bin 패키지의 일부입니다 (이는 배포판에 따라 다를 수 있음).
gtk-launch
다음과 같이 사용됩니다.
gtk-launch APPLICATION [URI...]
gtk-launch app-name.desktop
gtk-launch app-name
그주의 사항 gtk-launch
요구 의 .desktop (즉, 위치 설치 될 파일 /usr/share/applications
또는 ~/.local/share/applications
).
따라서이 문제를 해결하기 위해 원하는 .desktop 파일을 시작하기 전에 임시로 설치하는 해시 작은 Bash 기능을 사용할 수 있습니다 . .desktop 파일 을 설치하는 "올바른"방법은 사용하는 desktop-file-install
것이지만 무시하겠습니다.
launch(){
# Usage: launch PATH [URI...]
# NOTE: The bulk of this function is executed in a subshell, i.e. `(..)`
# This isn't strictly necessary, but it keeps everything
# out of the global namespace and lessens the likelihood
# of side effects.
(
# where you want to install the launcher to
appdir=$HOME/.local/share/applications
# the template used to install the launcher
template=launcher-XXXXXX.desktop
# ensure $1 has a .desktop extension, exists, is a normal file, is readable, has nonzero size
# optionally use desktop-file-validate for stricter checking
# desktop-file-validate "$1" 2>/dev/null || {
[[ $1 = *.desktop && -f $1 && -r $1 && -s $1 ]] || {
echo "ERROR: you have not supplied valid .desktop file" >&2
return 1
}
# ensure the temporary launcher is deleted upon exit
trap 'rm "$launcherfile" &>/dev/null' EXIT
# create a temp file to overwrite later
launcherfile=$(mktemp -p "$appdir" "$template")
launchername=${launcherfile##*/}
# overwrite temp file with the launcher file
if cp "$1" "$launcherfile" &>/dev/null; then
gtk-launch "$launchername" "${@:2}"
else
echo "ERROR: failed to copy launcher to applications directory" >&2
return 1
fi
)
}
당신은 그렇게 사용할 수 있습니다 (또한 원하는 경우 추가 인수 또는 URI를 전달하십시오).
launch PATH [URI...]
launch ./path/to/shortcut.desktop
수동 대안
.desktop 파일 을 수동으로 구문 분석하고 실행 하려면 다음 awk
명령을 사용하십시오.
awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop
awk
명령을 올인원 스크립트처럼 취급하려는 경우 Exec 명령을 찾을 수없는 경우 오류 메시지를 표시하고 리턴 코드 1로 종료 할 수도 있습니다 .
awk 'BEGIN {command=""} /^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); command=$0; exit} END {if (command!="") {exit system(command)} else {if (FILENAME == "-") {printf "ERROR: Failed to identify Exec line\n" > "/dev/stderr"} else {printf "ERROR: Failed to identify Exec line in \047%s\047\n", FILENAME > "/dev/stderr"} close("/dev/stderr"); exit 1}}'
위에서 언급 한 명령은 다음과 같습니다.
- Exec =로 시작하는 줄을 찾으십시오.
- Exec =를 제거하십시오
- 어떤 Exec에서 변수를 제거합니다 (예를 들어
%f
, %u
, %U
). 사양에서 의도 한대로 이러한 인수를 위치 인수로 대체 할 수 있지만 그렇게하면 문제가 상당히 복잡해집니다. 최신 데스크탑 항목 사양을 참조하십시오 .
- 명령을 실행
- 적절한 종료 코드로 즉시 종료하십시오 (여러 개의 Exec 행을 실행하지 않도록 )
이 AWK 스크립트는 다른 답변들 중 일부에 의해 적절히 해결되거나 해결되지 않을 수있는 몇 가지 최첨단 사례를 다룹니다. 특히,이 명령은 여러 제거 Exec에서의 단일 실행됩니다, 변수 (그렇지 않으면 % 기호를 제거하지 않도록주의하면서)를 Exec을 줄 명령을, 예상대로해도 동작합니다 Exec을 줄 명령은 하나 이상의 등호 포함 (예를 script.py --profile=name
).
다른 몇 가지주의 사항 ... 사양에 따르면 TryExec 은 다음과 같습니다.
프로그램이 실제로 설치되었는지 확인하는 데 사용되는 디스크의 실행 파일 경로입니다. 경로가 절대 경로가 아닌 경우 파일은 $ PATH 환경 변수에서 조회됩니다. 파일이 없거나 실행 가능하지 않은 경우 항목이 무시 될 수 있습니다 (예 : 메뉴에서 사용되지 않음).
그것을 염두에두고, 가치를 실행하는 것은 의미가 없습니다.
다른 관심사는 Path and Terminal 입니다. 경로 는 프로그램을 실행하는 작업 디렉토리로 구성됩니다. 터미널 은 프로그램이 터미널 창에서 실행되는지 여부를 나타내는 부울입니다. 이것들은 모두 다룰 수 있지만, 이미 사양의 구현이 있기 때문에 바퀴를 재발 명하는 것은 의미가 없습니다. Path 를 구현 하려면 system()
하위 프로세스 를 생성하므로 다음과 같은 작업을 수행하여 작업 디렉토리를 변경할 수 없습니다 system("cd \047" working_directory "\047"); system(command)
. 그러나 아마도 당신은 같은 것을 할 수 system("cd \047" working_directory "\047 && " command)
있습니다. 참고 \ 047은 작은 따옴표입니다 (따라서 명령은 공백이있는 경로에서 중단되지 않습니다).
파이썬 대안
나는 카를로에서 페이지를 훔치는거야 여기 의 사용하기 위해 파이썬 스크립트를 작성 제안, 병사 모듈을. 다음은 파일을 작성하지 않고 I / O에 대해 걱정할 필요없이 쉘에서 동일한 코드를 실행하는 최소한의 방법입니다.
launch(){
# Usage: launch PATH [URI...]
python - "$@" <<EOF
import sys
from gi.repository import Gio
Gio.DesktopAppInfo.new_from_filename(sys.argv[1]).launch_uris(sys.argv[2:])
EOF
}
그런 다음 다음과 같이 런처 기능을 실행하십시오.
launch ./path/to/shortcut.desktop
URI 사용은 선택 사항입니다. 또한 오류 검사가 수행되지 않으므로 스크립트를 내구성있게하려면 시작 프로그램이 존재하고 읽을 수 있는지 (사용하기 전에) 확인해야합니다.
exec
실패한 이유 는 exec가 현재 실행중인 프로세스를 지정한 프로세스로 교체하기 때문에 쉘을 데스크탑을 컴파일 된 바이너리로 실행하는 것으로 바꾸려고했기 때문입니다. 당신이 할 수 없었던 이유sudo exec
는 바이너리 명령이 아니라 쉘 내장이기 때문입니다.