2017-05-29 1 views
1

Je cette ligne de code:salpingite d'un processus chronométré, avec la sortie du temps

{ time cp $PWD/my_file $PWD/new_file ; } 2> my_log.log 

J'ai besoin de savoir combien de temps il faut pour exécuter la commande « cp » et je dois aussi obtenir le PID du 'cp'. Je veux juste imprimer le PID du processus « cp » et obtenir ce qui suit dans le fichier my_log.log:

<output of time> 

J'ai essayé PID=$! mais cela ne fournit pas PID du processus cp.

+0

Vous voulez savoir PID cp ou le PID du processus en cours d'exécution en arrière-plan? Est-ce que vous copiez des charges de fichiers? – LethalProgrammer

+0

Ce n'est pas vraiment clair .... vous voulez seulement le pid du processus 'cp' dans le fichier journal? Voulez-vous la sortie de l'heure sur la sortie standard? –

Répondre

2
  • D'abord, vous devez envoyer votre (chronométré) commande cp à l'arrière-plan avec un & arrière, afin que vous puissiez contrôler les processus en cours après son lancement. (Je suppose que vous faites déjà cela, mais ce n'est pas actuellement reflété dans la question).

  • $!, la variable spéciale qui contient le PID du dernier lancé en tâche de fond, dans ce cas reflète la sous-shell qui exécute la commande time, donc nous savons que c'est le processus parentdu cp commander. Pour obtenir le (seul et unique, dans ce cas) processus enfant:

    • Si votre plate-forme a le nonstandard pgrep utilitaire (est livré avec de nombreuses distributions Linux et les plates-formes BSD/Mac OS), utilisez:
      pgrep -P $!

    • Sinon, utilisez l'approche conforme POSIX suivante:
      ps -o pid=,ppid= | awk -v ppid=$! '$2 == ppid { print $1 }'

Pour mettre tous ensemble, en utilisant prgep pour des raisons pratiques:

# Send the timed `cp` command to the background with a trailing `&` 
{ time cp "$PWD/my_file" "$PWD/new_file"; } 2> my_log.log & 

# Get the `cp` comand's PID via its parent PID, $! 
cpPid=$(pgrep -P $!) 
0

Le plus simple que je peux penser est

pgrep cp 
+0

'(heure cp $ PWD/mon_fichier $ PWD/nouveau_fichier & 2>&1; echo $!)> My_log.log 2> & 1' Le contenu de my_log.log sera le PID de la commande cp suivi de la sortie de la commande cp. – Deathgrip

+0

OK - affichera réponse. – Jack

0

OK - des commentaires: « Contenu de my_log.log seront PID de la commande cp suivie par la sortie de synchronisation de la commande cp »:

(time cp $PWD/my_file $PWD/new_file & 2>&1; echo $!) > my_log.log 2>&1 

d'abord, vous devez utiliser /usr/bin/time explicitement, et transmettre les options à ajouter à un fichier de sortie. Ensuite, utilisez pgrep sur le nom du fichier que vous copiez (cp obtiendrez trop de hits):

/usr/bin/time --output=my_log.log --append cp $PWD/my_file $PWD/new_file & pgrep -f my_file > my_log.log 

Vous pouvez modifier le format de sortie, car il est un peu laid:

18400 
0.00user 0.30system 0:02.43elapsed 12%CPU (0avgtext+0avgdata 2520maxresident)k 
0inputs+496424outputs (0major+141minor)pagefaults 0swaps 
0

à la suite de ce qui écrit dans l'un de vos commentaires ci-dessus ... ce qui suit est une réponse appropriée:

le code suivant (juste un exemple):

time (sleep 10 & echo -n "$!"; wait) 

retournera quelque chose comme:

30406 
real 0m10.009s 
user 0m0.004s 
sys 0m0.005s 

Dans votre cas:

time (cp $PWD/old_file $PWD/new_file & echo -n "$!"; wait) &> my_log.log 

fera le travail.

Je trouve cette solution assez élégante car c'est un "one liner" malgré le "overhead complètement négligeable" que vous avez dans le timing (le timing sera lié à l'ensemble du sous-shell (aussi le echo et le wait). les frais généraux est négligeable est évident à partir du résultat de la commande du sommeil.

stdout redirect &> et stderr dans le même fichier (de sorte que vous n'avez pas besoin de spécifier le 1>&2).

faites attention que faire

(time sleep 10 & echo -n "$!") 

Vous obtiendrez le pid du processus time pas sleep ou cp dans votre cas.

2

Pour en savoir combien de temps prend la commande cp vous pouvez vérifier nouvelle taille du fichier

size=$(stat -c %s "${old_file}") 
cp "${old_file}" "${new_file}" & 
cp_pid=$! 
while kill -0 ${cp_pid}; do 
    cpsize=$(stat -c %s "${new_file}") 
    echo elapsed time $(ps -p${cp_pid} -oetime=) 
    echo $((100*cpsize/size)) % done so far.. 
    sleep 3 
done 

EDIT: commentaire suivant stat -c %s "${file}" peut être remplacé par du "${file}" il est commande POSIX et plus approprié (voir page man).

+0

Bien fait. Il vaut la peine de mentionner que 'stat' n'est pas un utilitaire POSIX et que sur BSD/macOS vous devrez utiliser' stat -f% z' à la place. – mklement0

+0

Belle idée, mais semble sans rapport avec la question .... :) –

+0

Pourquoi n'utilisez-vous pas 'du $ {old_file}' au lieu de 'stat'? 'du' devrait être un utilitaire POSIX. –