Як ми можемо отримати командний рядок запущеної програми?


16

В Ubuntu програми можна відкрити з терміналу. Але іноді незрозуміло, яка відповідна команда - це зробити.

Отже, відкриваючи програму, як я можу отримати команду, яка використовується для її запуску, без необхідності пошуку в будь-якому місці (лише дивлячись на неї)?

Відповіді:


13

Я тільки що зробив наступний скрипт, який використовує заголовок вікна програми, щоб дізнатися правильну команду, яка відкриває відповідну програму з терміналу (я назвав її appcmd):

#!/bin/bash

#appcmd - script which use the application window title to find out the right command which opens the respective application from terminal

#Licensed under the standard MIT license:
#Copyright 2013 Radu Rădeanu (http://askubuntu.com/users/147044/).
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

#check if wmctrl is installed
if [ ! -n "$(dpkg -s wmctrl 2>/dev/null | grep 'Status: install ok installed')" ]; then
    echo -e "The package 'wmctrl' must to be installed before to run $(basename $0).\nUse 'sudo apt-get install wmctrl' command to install it."
    exit
fi

window_title=$(echo $@ | awk '{print tolower($0)}')
windows=$(mktemp)
pids=$(mktemp)
pid_found=""

wmctrl -l | awk '{$2=$3=""; print $0}' > $windows

cat $windows | while read identity window; do
    if [[ $(echo $window | awk '{print tolower($0)}') == *$window_title* ]]; then
        wmctrl -lp | grep -e "$identity.*$window" | awk '{$1=$2=$4=""; print $0}'
    fi
done > $pids

while read pid window; do
    if [ "$pid" != "0" -a "$window" != "Desktop" ]; then
        echo -e "Application window title:\t$window"
        echo -e "Command to open from terminal:\t\$ $(ps -o command $pid | tail -n 1)\n"
        pid_found="$pid"
    fi
done < $pids

if [ "$pid_found" = "" ]; then
    echo "There is no any opened application containing '$@' in the window title."
fi

Збережіть цей скрипт у своєму ~/binкаталозі і не забудьте зробити його виконуваним:

chmod +x ~/bin/appcmd

Використання:

  • Коли сценарій буде запущений без жодних аргументів, сценарій поверне всі команди для всіх відкритих вікон відповідними.

  • Якщо наведено якийсь аргумент, скрипт спробує знайти відкрите вікно програми, що містить у своєму заголовку цей аргумент, і поверне відповідну команду. Наприклад, якщо браузер Chromium відкритий, ви можете дізнатися команду, яка відкриває його з терміналу, використовуючи лише:

    appcmd chromium
    

@ RaduRădeanu: чудово працює .. :) RaduRădeanu , ти чудовий .. !!
Саурав Кумар

Я не пробував ваш сценарій, але чи повертає він перемикачі, які також використовуються? Наприклад, я запускаю leafpad, текстовий редактор, наприклад: leafpad --tab-width=2. Чи включатиме ваш вихід --tab-width=2?

@ vesa1 Ну, можна спробувати. Я зараз не leafpadвстановив, але для деяких додатків так, також поверне аргументи.
Раду Радеану

12

Від сюди :

xprop | awk '($1=="_NET_WM_PID(CARDINAL)") {print $3}' | xargs ps h -o pid,cmd

Якщо вам потрібен лише командний рядок, то просто:

xprop | awk '($1=="_NET_WM_PID(CARDINAL)") {print $3}' | xargs ps h -o cmd

Після запуску команди просто натисніть на вікно, для якого потрібно показати команду запуску.


Дякую! Я ніколи не зрозумів би це самостійно.
ksoo

1
Було б солодко, якби це було включено як вихід xwininfo ...
virtualxtc

@ RaduRădeanu Потім використовуйте тачпад. :) Насправді моя відповідь була перенесена з цього дублюючого запитання, в якому явно попросили метод кліку.
сокольниця

6

Альтернативний сценарій:

#!/bin/bash

# Copyright © 2013  minerz029
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

shopt -s extglob

for var in 'wm_pid' 'wm_name' 'wm_class' 'cmdline' 'wm_id'; do
    declare "$var"'=Not found'
done

notify-send -t 3000 'Click on a window to get the command line...'
xprop_out="$(xprop)"

while IFS=$'\n' read -r -d $'\n' line; do
    if [[ "$line" == '_NET_WM_PID(CARDINAL) = '* ]]; then
        wm_pid="${line#_NET_WM_PID(CARDINAL) = }"
    elif [[ "$line" == 'WM_NAME('?(UTF8_)'STRING) = '* ]]; then
        wm_name="${line#WM_NAME(?(UTF8_)STRING) = }"
    elif [[ "$line" == 'WM_CLASS('?(UTF8_)'STRING) = '* ]]; then
        wm_class="${line#WM_CLASS(?(UTF8_)STRING) = }"
    elif [[ "$line" == 'WM_CLIENT_LEADER(WINDOW): window id # '* ]]; then
        wm_id="${line#WM_CLIENT_LEADER(WINDOW): window id # }"
    fi
done <<< "$xprop_out"

if [[ "$wm_pid" == +([0-9]) ]]; then
    quote () 
    { 
        local quoted="${1//\'/\'\\\'\'}";
        out="$(printf "'%s'" "$quoted")"
        if eval echo -n "$out" >/dev/null 2>&1; then
            echo "$out"
        else
            echo "SEVERE QUOTING ERROR"
            echo "IN: $1"
            echo -n "OUT: "
            eval echo -n "$out"
        fi
    }
    cmdline=()
    while IFS= read -d '' -r arg; do
        cmdline+=("$(quote "$arg")")
    done < "/proc/$wm_pid/cmdline"
fi

text="\
Title:
    $wm_name
Class:
    $wm_class
ID:
    $wm_id
PID:
    $wm_pid

Command line:
    ${cmdline[@]}"

copy() {
    { echo -n "$1" | xsel -i -b >/dev/null; } && xsel -k
}

if [[ -t 1 ]]; then
    echo "$text"
    if [[ "$1" == '--copy' ]]; then
        echo "Copied"
        copy "$cmdline"
    fi
else
    zenity \
        --title='Window information' \
        --width=750 \
        --height=300 \
        --no-wrap \
        --font='Ubuntu Mono 11' \
        --text-info \
        --cancel-label='Copy' \
        --ok-label='Close' \
    <<< "$text"
    if [[ $? == 1 ]]; then
        copy "$cmdline"
    fi
fi

Використання:

  1. Збережіть вищезазначений скрипт у файлі та зробіть його виконуваним.
  2. Запустіть файл, двічі клацнувши та вибравши «Виконати».
  3. Клацніть на вікні, в якому ви хочете знати команду.
  4. Інформація буде показана вам. (Заголовок, PID, ID, клас та командний рядок)
  5. Ви можете натиснути кнопку "Копіювати", щоб скопіювати командний рядок у буфер обміну.
    Для цього потрібно встановити xselВстановити xsel .

введіть тут опис зображення


1
дуже приємне виконання сценаріїв оболонок. +1 від мене
souravc

4

В якості альтернативи, не потребуючи сценарію, ви можете просто відкрити монітор системи та навести курсор миші на процес, про який ви хочете знати командний рядок.

Якщо ввімкнути "Перегляд залежностей", ви зможете побачити, який процес називається іншим, так, наприклад, ви можете побачити різні процеси, які Chrome створює для кожної вкладки, і відстежити її до батьківського процесу, який матиме командний рядок з яким Chrome було викликано (користувачем).


Це не буде працювати весь час. Швидкий приклад - менеджер файлів за замовчуванням від Ubuntu - Nautilus.
Radu Rădeanu

@ RaduRădeanu Звичайно, це не отримує команду від альтернативного імені (Файли) nautilus, але якщо ви просто хочете простий спосіб отримати аргументи, це буде добре. Ви все ще можете розпізнати ікону
kiri

1

Найбільш схожа думка, яку я знайшов, - це xwininfo, яка дає вам інформацію про запущене вікно. Але це не говорить вам, яка програма працює в ній.


0

Ще один спосіб перерахувати ім'я команди та аргументи запущених процесів:

ps axk pid,comm o comm,args > output.txt

(Перенаправлення у файл, щоб імена / аргументи команд не були усічені.)

Джерело: man psрозділ прикладів (з невеликою модифікацією).

Системний монітор - це графічний інтерфейс для ps.


Ви завжди grepможете знайти команду, якщо маєте розпливчасте уявлення.
кірі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.