ทางที่ถูก
คุณควรใช้งานจริง ๆgtk-launch
ถ้ามี มันมักจะเป็นส่วนหนึ่งของแพคเกจlibgtk-3-bin (ซึ่งอาจแตกต่างกันไปตาม distro)
gtk-launch
ใช้ดังนี้:
gtk-launch APPLICATION [URI...]
gtk-launch app-name.desktop
gtk-launch app-name
โปรดทราบว่าgtk-launch
จำเป็นต้องติดตั้งไฟล์ . desktop (เช่นอยู่ใน/usr/share/applications
หรือ~/.local/share/applications
)
ดังนั้นเพื่อให้ได้สิ่งนี้เราสามารถใช้ฟังก์ชั่น 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
)
}
คุณสามารถใช้มันได้เช่นกัน (และส่งต่ออาร์กิวเมนต์หรือ URIs เพิ่มเติมหากคุณต้องการ):
launch PATH [URI...]
launch ./path/to/shortcut.desktop
ทางเลือกด้วยตนเอง
หากคุณต้องการแยกวิเคราะห์และเรียกใช้ไฟล์ . desktopด้วยตนเองคุณสามารถทำได้ด้วยawk
คำสั่งต่อไปนี้:
awk '/^Exec=/ {sub("^Exec=", ""); gsub(" ?%[cDdFfikmNnUuv]", ""); exit system($0)}' app-name.desktop
หากคุณต้องการใช้awk
คำสั่งเหมือนสคริปต์แบบ all-in-one เราสามารถแสดงข้อความแสดงข้อผิดพลาดและออกด้วยรหัสส่งคืน 1 ในกรณีที่ไม่พบคำสั่งExec :
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
) เป็นไปได้ที่จะแทนที่สิ่งเหล่านี้ด้วยอาร์กิวเมนต์ตำแหน่งในขณะที่สเปคตั้งใจ แต่การทำเช่นนั้นจะเพิ่มความซับซ้อนที่สำคัญให้กับปัญหา ดูล่าสุดจำเพาะ Entry สก์ท็อป
- ดำเนินการคำสั่ง
- ออกทันทีด้วยรหัสออกที่เหมาะสม (เพื่อไม่ให้ทำงานExecหลายสาย)
หมายเหตุสคริปต์ AWK นี้ระบุกรณีขอบบางกรณีที่อาจตอบสนองหรือไม่ตอบคำถามอื่น ๆ ได้อย่างเหมาะสม โดยเฉพาะคำสั่งนี้จะลบตัวแปรExecหลายตัว (ระวังไม่ให้ลบสัญลักษณ์%) ออกไป, จะดำเนินการคำสั่งExecบรรทัดเดียวเท่านั้น, และจะทำงานตามที่คาดไว้แม้ว่าคำสั่งExec line จะมีเครื่องหมายเท่ากับหนึ่งเครื่องหมายขึ้นไป (เช่นscript.py --profile=name
)
เพียงไม่กี่ประการอื่น ... ตามข้อกำหนดTryExecคือ:
พา ธ ไปยังไฟล์ที่เรียกใช้งานได้บนดิสก์ที่ใช้เพื่อตรวจสอบว่ามีการติดตั้งโปรแกรมจริงหรือไม่ หากพา ธ ไม่ใช่พา ธ สัมบูรณ์ไฟล์จะค้นหาในตัวแปรสภาพแวดล้อม $ PATH หากไฟล์นั้นไม่มีอยู่หรือไม่สามารถเรียกใช้งานได้รายการนั้นอาจถูกละเว้น (ไม่ได้ใช้ในเมนูตัวอย่าง)
โดยที่ในใจมันไม่สมเหตุสมผลเลยที่จะเรียกใช้คุณค่าของมัน
บางคนกังวลอื่น ๆ ที่มีเส้นทางและเทอร์มิ พา ธประกอบด้วยไดเรกทอรีทำงานเพื่อเรียกใช้โปรแกรมเทอร์มินัลคือบูลีนที่ระบุว่าโปรแกรมนั้นทำงานในหน้าต่างเทอร์มินัลหรือไม่ สิ่งเหล่านี้สามารถแก้ไขได้ แต่ไม่มีเหตุผลในการปรับแต่งวงล้อใหม่เนื่องจากมีการติดตั้งสเป็คแล้ว หากคุณต้องการนำPathไปใช้โปรดจำไว้ว่าsystem()
วางกระบวนการย่อยไว้ดังนั้นคุณไม่สามารถเปลี่ยนไดเร็กตอรี่ที่ใช้งานsystem("cd \047" working_directory "\047"); system(command)
ได้ system("cd \047" working_directory "\047 && " command)
แต่คุณคงจะสามารถทำสิ่งที่ชอบ หมายเหตุ \ 047 เป็นเครื่องหมายคำพูดเดี่ยว (ดังนั้นคำสั่งจะไม่หยุดพักบนเส้นทางที่มีช่องว่าง)
ทางเลือกหลาม
ฉันขโมยหน้าเว็บจาก Carlo ที่นี่ผู้แนะนำให้สร้างสคริปต์ Python เพื่อใช้โมดูลgi นี่เป็นวิธีที่น้อยที่สุดในการรันโค้ดเดียวกันจากเชลล์โดยไม่ต้องสร้างไฟล์และกังวลเกี่ยวกับ 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
โปรดทราบว่าการใช้ URIs นั้นเป็นทางเลือก นอกจากนี้ยังไม่มีการตรวจสอบข้อผิดพลาดดังนั้นคุณจึงต้องการมั่นใจว่าตัวเรียกใช้งานนั้นมีอยู่และสามารถอ่านได้ (ก่อนใช้งาน) หากคุณต้องการให้สคริปต์ของคุณทนทาน
exec
ล้มเหลวเนื่องจาก exec แทนที่กระบวนการที่คุณกำลังดำเนินการอยู่ในปัจจุบันด้วยกระบวนการที่คุณระบุดังนั้นสิ่งที่คุณทำคือพยายามแทนที่เชลล์ของคุณด้วยการรันเดสก์ท็อปเป็นไบนารีที่รวบรวม เหตุผลที่คุณทำไม่ได้sudo exec
เพราะมันเป็นเชลล์ที่มีอยู่แล้วไม่ใช่คำสั่งไบนารี