• Opret dig
  • Glemt adgangskode

User account menu

  • Artikler
  • Forside
  • Forum
  • Nyheder
  • Log ind
Hjem
LinuxIN.dk

Snak med

Opret dig!

Af uldall | 25.02.2011 19:13

Hjælp til for-loop og cp

Programmering
Hej alle.
Jeg er ved at lave et script der kan gemme videoer fra fx Youtube på min computer.
Først findes programmets PID ved at køre

lsof | grep deleted | head -1 | awk '{ print $2 }'

Dette gemmes i en variabel kaldet $PID
Selve filerne findes i /proc/$PID/fd, så for at finde alle flash-filer køres følgende:

file $(find /proc/$PID/fd/ -print) | grep Flash | sort --u

Dette giver følgende output:

/proc/$PID/fd/17: broken symbolic link to `/tmp/FlashXXfPBaTM (deleted)'

Her får jeg altså både navnet på filen i /proc (/proc/$PID/fd/17) samt filens originale sti (/tmp/FlashXXfPBaTM).

Problem:
Jeg kunne nu godt tænke mig at lave et for-loop, der tager output af file-kommandoen og indsætter det i en cp-kommando, så kommandoen kommer til at lyde:

cp /proc/$PID/fd/17 /tmp/FlashXXfPBaTM


Herunder er scriptet i dens nuværende stand, som kopierer filer direkte. Dvs. at den kopierer /proc/$PID/fd/17 til /tmp/17 og ikke /tmp/FlashXXfPBaTM som ønsket.

PID=$(lsof | grep deleted | grep plugin-co | head -1 | awk '{ print $2 }')
for i in $(file $(find /proc/$PID/fd/ -print) | grep Flash | sort --u | awk '{ print $1 }' | sed 's/.$//')
do
echo "Now copying: $i to /tmp"
cp $i /tmp
echo "Done!"
done

  • Log ind eller opret dig for at tilføje kommentarer

Kommentarer8

# 1

15 år siden

Permalink

Indsendt af Tom_the_ den 25. februar 2011 kl. 20:13

Permalink

Det er ikke for at være

Det er ikke for at være lyseslukker, men hvorfor ikke bare bruge firefox til at hente en fil fra youtube. De ligger da i mp4 format.
  • Log ind eller opret dig for at tilføje kommentarer

# 2

15 år siden

Permalink

Indsendt af mixi den 25. februar 2011 kl. 20:31

Permalink

Eller hvad med at bruge :

Eller hvad med at bruge : http://rg3.github.com/youtube-dl/
  • Log ind eller opret dig for at tilføje kommentarer

# 3

15 år siden

Permalink

Indsendt af uldall den 25. februar 2011 kl. 21:52

Permalink

Jep, jeg kender godt til

Jep, jeg kender godt til youtube-dl, men jeg lærer jo ingenting ved bare at bruge en andens program.

Og nu har jeg altså valgt et problem, som jeg mener kan løses med et for-loop, som dog driller.

Men tak for inputtet, hvis jeg havde haft et "reelt" problem og bare skulle have en hurtig løsning, var det de helt rigtige svar:-)
  • Log ind eller opret dig for at tilføje kommentarer

# 4

15 år siden

Permalink

Indsendt af mixi den 26. februar 2011 kl. 01:26

Permalink

okay... jeg undskylder, jeg

okay... jeg undskylder, jeg havde misforstået det, men så vidt jeg kan se fra dit kode eksemple, så mangler der et ";" i dit for-loop.
eksemple:

for i in $( ls ); do
echo item: $i
done

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html
  • Log ind eller opret dig for at tilføje kommentarer

# 5

15 år siden

Permalink

Indsendt af mrbrown79 den 26. februar 2011 kl. 13:01

Permalink

PID=$(lsof | grep deleted |


PID=$(lsof | grep deleted | grep plugin-co | head -1 | awk '{ print $2 }')
for i in $(file $(find /proc/$PID/fd/ -print) | grep Flash | sort --u | awk '{ print $1 }' | sed 's/.$//')
do
echo "Now copying: $i to /tmp"
cp $i /tmp
echo "Done!"
done


I sådan nogle tilfælde plejer jeg at bruge awk til at generere kommandolinjen og så pipe til shell'en (m.a.o: drop for-løkkerne).
Fx:

PID=$(lsof | grep deleted | grep plugin-co | head -1 | awk '{ print $2 }')
file $(find /proc/$PID/fd/ -print) | grep Flash | sort --u | sed -e 's/://g' -e 's/`//g' | awk '{ print "cp " $1 " " $6 }' | sh


Hvis du vil have den til at udskrive noget, så kan du jo udbygge awk-linjen efter bedste evne - fx:

file $(find /proc/$PID/fd/ -print) | grep Flash | sort --u | sed -e 's/://g' -e 's/`//g' | awk '{ print "printf \"Copying " $1 "...\""; print "cp " $1 " " $6 " && echo Done!"; }' | sh


Anyway, hvis du foretrækker for-loops, så burde det være muligt at tildele flere argumenter i stil med eksempel 11.2 her: http://tldp.org/LDP/abs/html/loops1.html . Jeg har dog ikke haft held med at få det til at virke.

  • Log ind eller opret dig for at tilføje kommentarer

# 6

15 år siden

Permalink

Indsendt af uldall den 26. februar 2011 kl. 13:24

Permalink

Så fik jeg den næsten

Så fik jeg den næsten ordnet, men et nyt problem er opstået:

Jeg har nu fået den til at kopiere en enkelt fil som jeg gerne vil have det, men modsat scriptet i min første post, begynder den ikke automatisk på næste fil.

Jeg går stærkt ud fra, at det har noget at gøre med, at jeg sætter gåseøjne (") omkring et flerlinjet output i dette stykke:

for i in "$(file $(find /proc/$PID/fd/ -print) | grep Flash | sort -u)";

I mit tilfælde ved jeg, at der ligger 3 flash-filer i /proc/$PID/fd/.

Her er scriptet som det ser ud nu:

#!/bin/bash
# Variables
PID=$(lsof | grep deleted | grep plugin-co | head -1 | awk '{ print $2 }')
COUNT=$(file $(find /proc/$PID/fd/ -print) | grep Flash | sort -u | wc -l)

# Script
echo "PID is $PID and we got $COUNT files to copy..."
for i in "$(file $(find /proc/$PID/fd/ -print) | grep Flash | sort -u)";
do
# Variables
PROC=$(echo $i | awk '{ print $1 }' | sed 's/.$//')
TMP=$(echo $i | awk '{ print $6 }' | cut -c2-)
# Commands
echo "Now copying: $PROC to $TMP"
cp $PROC $TMP
echo "Done!"
done
  • Log ind eller opret dig for at tilføje kommentarer

# 7

15 år siden

Permalink

Indsendt af mrbrown79 den 26. februar 2011 kl. 13:46

Permalink

Jeg går stærkt ud fra, at


Jeg går stærkt ud fra, at det har noget at gøre med, at jeg sætter gåseøjne (") omkring et flerlinjet output i dette stykke:

Ja, præcis. Løkken afvikles kun en enkelt gang, så (prøv at echo $i for at se om den indeholder multiple linjer når der er flere filer).

Så du mit indlæg #5 inden du skrev?
  • Log ind eller opret dig for at tilføje kommentarer

# 8

15 år siden

Permalink

Indsendt af uldall den 26. februar 2011 kl. 15:01

Permalink

(prøv at echo $i for at se

Nej, jeg så ikke dit indlæg før jeg postede, men det virker i hvert fald som det skal, når jeg kører din kommando, jeg har dog udbygget den lidt, så den printer en tekst der ligger mere op ad hvad jeg havde tænkt mig. Jeg havde slet ikke tænkt på, at awk ville kunne klare problemet.

Jeg har før kørt echo $i, hvilket bekræfter min hypotese om at den indeholder flere linjer.

Min modifikation af din kommando-linje ser således ud:

#!/bin/bash

# Variables
PID=$(lsof | grep deleted | grep plugin-co | head -1 | awk '{ print $2 }')
COUNT=$(file $(find /proc/$PID/fd/ -print) | grep Flash | sort -u | wc -l)

# Script
echo "PID is $PID and we have $COUNT files to copy..."
file $(find /proc/$PID/fd/ -print) | grep Flash | sort -u | sed -e 's/://g' -e 's/`//g' | awk '{ print "printf \"Copying " $1 " to " $6 "...\""; print "cp " $1 " " $6 " && echo Done!"; }' | sh
echo "Done copying $COUNT files."

  • Log ind eller opret dig for at tilføje kommentarer

Svar søges

KDE Plasma 6.6 skrivebordsmiljø udgivet 0
youtube-tui: Nyd YouTube fra terminalen som en professionel 0
GRUB 2.14 introducerer understøttelse af EROFS, forbedringer til Btrfs og LVM 0
KDE Plasma 6.6 tilføjer en funktion, som brugerne har spurgt efter i evigheder 0
Linux i København 12.01.2026: Open source i det offentlige 0

Seneste aktivitet

Det engang så elskede PCLinuxOS er tilbage - og det er stadig en fantastisk Windows erstatning 1
rsync og filsystem 6
Mousam er en detaljeret desktop vejrapp til Linux 1
Hjælp til Handbrake - ingen dk-undertekster 1
BigLinux 4
luckyBackup 2
GIMP 30
Pinegrow på Debian 13 ? 4
Openmediavault 1
E-mail blues 9
Driver til min scanner? 5
Printer Epson ET-2865 problem 16
Sudo 7
Thunderbird filvedligeholdelse 2
Debian 13.3.0 8
Linux Mint 22.3 - hvornår opdatere? 10
Canon-printer: Jeg savner "Ink-Toner Level"-meddelelse 10
billede af nuværende installation 2
mapper 4
LinuxIn live 9

© 2026 Linuxin og de respektive skribenter

Oprettet og drevet af nørder siden 2004 !