Come possiamo ottenere la riga di comando di un'applicazione in esecuzione?


16

In Ubuntu, le applicazioni possono essere aperte da un terminale. Ma a volte non è chiaro quale sia il comando appropriato per farlo.

Quindi, avendo un'applicazione aperta, come posso ottenere il comando usato per avviarlo, senza dover cercare da nessuna parte (semplicemente guardandolo)?

Risposte:


13

Ho appena creato il seguente script che usa il titolo della finestra dell'applicazione per scoprire il comando giusto che apre la rispettiva applicazione dal terminale (l'ho chiamato 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

Salva questo script nella tua ~/bindirectory e non dimenticare di renderlo eseguibile:

chmod +x ~/bin/appcmd

Uso:

  • Quando lo script viene eseguito senza alcun argomento, lo script restituirà tutti i comandi per tutte le finestre aperte corrispondenti.

  • Se viene fornito un argomento, lo script proverà a trovare una finestra dell'applicazione aperta contenente nel titolo tale argomento e restituirà il comando corrispondente. Ad esempio, se il browser Chromium è aperto, puoi trovare il comando che lo apre dal terminale usando solo:

    appcmd chromium
    

@ RaduRădeanu: funziona alla grande .. :) RaduRădeanu , sei fantastico .. !!
Saurav Kumar,

Non ho provato il tuo script ma restituisce anche gli switch utilizzati? Per esempio, mi lancio leafpad, un editor di testo, come questo: leafpad --tab-width=2. La tua produzione includerebbe --tab-width=2?

@ vesa1 Beh, puoi provarlo. Non ho leafpadinstallato in questo momento, ma per alcune applicazioni sì, restituiranno anche gli argomenti.
Radu Rădeanu,

12

Da qui :

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

Se hai solo bisogno della riga di comando iniziale, basta:

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

Dopo aver eseguito il comando, fai clic sulla finestra per la quale desideri visualizzare il comando di avvio.


Grazie! Non avrei mai capito da solo.
ksoo,

1
Sarebbe bello se questo fosse incluso come output di xwininfo ...
virtualxtc

@ RaduRădeanu Quindi usa il tuo touchpad. :) In realtà la mia risposta è stata migrata da questa duplice domanda che chiedeva esplicitamente un metodo di clic.
falconiere,

6

Una sceneggiatura alternativa:

#!/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

Uso:

  1. Salvare lo script sopra in un file e renderlo eseguibile.
  2. Esegui il file facendo doppio clic e selezionando "Esegui".
  3. Fai clic sulla finestra di cui desideri conoscere il comando.
  4. Le informazioni ti verranno visualizzate. (Titolo, PID, ID, classe e riga di comando)
  5. È possibile fare clic sul pulsante "Copia" per copiare la riga di comando negli Appunti.
    Ciò richiede l' installazioneInstalla xsel di xsel .

inserisci qui la descrizione dell'immagine


1
ottima esecuzione degli script di shell. +1 da me
souravc

4

In alternativa, senza bisogno di uno script, puoi semplicemente aprire System Monitor e passare il mouse sul processo di cui desideri conoscere la riga di comando.

Se abiliti la "Visualizzazione dipendenze", sarai in grado di vedere quale processo ha chiamato un altro, quindi, ad esempio, puoi vedere i vari processi che Chrome crea per ciascuna scheda e rintracciarlo al processo padre che avrà la riga di comando con cui Chrome è stato invocato (dall'utente).


Questo non funzionerà sempre. Un rapido esempio è il file manager predefinito di Ubuntu - Nautilus.
Radu Rădeanu,

@ RaduRădeanu Ovviamente non ottiene il comando dal nome alternativo (Files) di nautilus, ma se vuoi solo un modo semplice per ottenere gli argomenti, questo funzionerà bene. Puoi ancora riconoscere l'icona
kiri,

1

La cosa più simile che ho trovato è xwininfo, che ti dà informazioni su una finestra in esecuzione. Ma non ti dice quale programma è in esecuzione al suo interno.


0

Un altro modo per elencare il nome del comando e gli argomenti dei processi in esecuzione è:

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

(Reindirizzare in un file in modo che i nomi / argomenti del comando non vengano troncati.)

Fonte: man pssezione esempi (con una piccola modifica).

Il monitor di sistema è una GUI per ps.


Puoi sempre usare grepper trovare il comando se hai una vaga idea.
Kiri,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.