LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-16-2014, 10:26 AM   #1
tonj
Member
 
Registered: Sep 2008
Posts: 546

Rep: Reputation: 37
SOLVED: trying to wrap long command


I'm running centos 6 64bit server (command line only)
this command works fine in a terminal:
Quote:
ffmpeg -i "rtmp://<ip-cam>" -f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast -crf 35 -c:a libfdk_aac -ac 1 -ab 32k -vf drawtext="fontfile=/usr/share/fonts/truetype/arialbd.ttf: text='my-text-here':fontsize=20:fontcolor=white:x=30:y=310" "rtmp://<red5-svr>"
it's a long single line however I want to put it into a startup script in /etc/init.d/ and I want to wrap the lines within the console window but I can't get it to work. I've seen other commands work ok with a '/' on the end of each line but it doesn't work for me. This is the first part of the script:
Quote:
#!/bin/sh
### BEGIN INIT INFO
# Provides: stream
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: start ffmpeg
### END INIT INFO

SCRIPT="ffmpeg -i "rtmp://<ip-camera>" \
-f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast \
-crf 35 -c:a libfdk_aac -ac 1 -ab 32k \
-vf drawtext="fontfile=/usr/share/fonts/truetype/arialbd.ttf: \
text='livebit.co.uk':fontsize=20:fontcolor=white:x=30:y=310" \
"rtmp://198.91.92.244:2501/live/livestream1""
RUNAS=root

PIDFILE=/var/run/stream.pid
LOGFILE=/var/log/stream.log

<snip>
I'm using putty on a windows 7 machine to create a terminal for access to the server. I've googled about this but I can't find the correct syntax to enable me to break and wrap the lines of this long command. The log keeps saying "Trailing options were found on the commandline". What am I doing wrong?

Last edited by tonj; 05-17-2014 at 10:43 AM. Reason: solved
 
Old 05-16-2014, 10:30 AM   #2
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
Code:
SCRIPT=$(ffmpeg -i "rtmp://<ip-camera>" \
-f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast \
-crf 35 -c:a libfdk_aac -ac 1 -ab 32k \
-vf drawtext="fontfile=/usr/share/fonts/truetype/arialbd.ttf: \
text='livebit.co.uk':fontsize=20:fontcolor=white:x=30:y=310" \
"rtmp://198.91.92.244:2501/live/livestream1")
How does that work?

Last edited by szboardstretcher; 05-16-2014 at 10:33 AM.
 
Old 05-16-2014, 10:58 AM   #3
tonj
Member
 
Registered: Sep 2008
Posts: 546

Original Poster
Rep: Reputation: 37
thanks for your response: good news and bad news:
your command works in that it starts ffmpeg but it causes a long scroll in the console and the stream.log file is not touched.
When the script works properly the console looks like this:
Quote:
# /etc/init.d/stream start
Starting service…
Service started
and if I tail /var/log/stream.log I can see details of the process running
but now it looks like this:
Quote:
# /etc/init.d/stream start
ffmpeg version git-2014-05-16-bac08cf Copyright (c) 2000-2014 the FFmpeg developers
built on May 16 2014 12:58:16 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
configuration: --prefix=/root/ffmpeg_build --extra-cflags=-I/root/ffmpeg_build/include --extra-ldflags=-L/root/ffmpeg_build/lib --bindir=/root/bin --extra-libs=-ldl --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libfreetype --enable-libspeex --enable-libtheora --enable-libfontconfig
libavutil 52. 83.100 / 52. 83.100
libavcodec 55. 62.100 / 55. 62.100
libavformat 55. 38.100 / 55. 38.100
libavdevice 55. 13.101 / 55. 13.101
libavfilter 4. 5.100 / 4. 5.100
libswscale 2. 6.100 / 2. 6.100
libswresample 0. 19.100 / 0. 19.100
libpostproc 52. 3.100 / 52. 3.100
Input #0, flv, from 'rtmp://212.159.70.205:1935/live/livestream1':
Metadata:
title : Media Presentation
encoder : Lavf55.37.102
length : 14
Duration: 00:00:00.00, start: 0.000000, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 10 fps, 10 tbr, 1k tbn, 20 tbc
Stream #0:1: Audio: aac, 8000 Hz, mono, fltp, 32 kb/s
[libx264 @ 0x3b28f40] using SAR=1/1
[libx264 @ 0x3b28f40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x3b28f40] profile High, level 2.2
[libx264 @ 0x3b28f40] 264 - core 142 r2 ac76440 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options:
etc...etc
and there's no activity in /var/log/stream.log.
 
Old 05-16-2014, 11:09 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
I would hazard a guess that whatever it is you are snipping is probably causing some problems.

May I ask why we are either storing the command in a variable (your first example) or capturing the output of the command into your variable (the example from next post)?

Is there an issue with simply executing it where it is needed within the script?
Are you using either of the above methods because your script is calling this command several times?
As a third alternative, if being called multiple times, perhaps you should place it in a function??
 
Old 05-16-2014, 11:19 AM   #5
tonj
Member
 
Registered: Sep 2008
Posts: 546

Original Poster
Rep: Reputation: 37
thanks but I hardly understand any of what you said, my knowledge isn't that good. I don't know what a variable is, or a function. I'm capturing the log with tail -f because it's the only way to confirm the script is working and ffmpeg is actually runnng, which at the moment it isn't. If it's not possible to wrap long lines within a bash script then ok but I don't know what can be done and what can't.
 
Old 05-16-2014, 11:42 AM   #6
szboardstretcher
Senior Member
 
Registered: Aug 2006
Location: Detroit, MI
Distribution: GNU/Linux systemd
Posts: 4,278

Rep: Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694Reputation: 1694
Can you post the whole script in a pastebin? http://paste.ubuntu.com/

Seeing the whole thing will help troubleshoot it, without causing problems further down the lines.
 
Old 05-16-2014, 04:29 PM   #7
tonj
Member
 
Registered: Sep 2008
Posts: 546

Original Poster
Rep: Reputation: 37
thanks for your response. This is the whole script - /etc/init.d/stream

Quote:
#!/bin/sh
### BEGIN INIT INFO
# Provides: stream
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: start ffmpeg
### END INIT INFO

SCRIPT="/root/bin/ffmpeg -i "rtmp://<ip-camera>" -f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast -crf 35 -c:a libfdk_aac -ac 1 -ab 32k "rtmp://<red5-server>"
RUNAS=root

PIDFILE=/var/run/stream.pid
LOGFILE=/var/log/stream.log

start() {
if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then
echo 'Service already running' >&2
return 1
fi
echo 'Starting service…' >&2
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"
echo 'Service started' >&2
}

stop() {
if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Service not running' >&2
return 1
fi
echo 'Stopping service…' >&2
kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
echo 'Service stopped' >&2
}

uninstall() {
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
local SURE
read SURE
if [ "$SURE" = "yes" ]; then
stop
rm -f "$PIDFILE"
echo "Notice: log file is not be removed: '$LOGFILE'" >&2
update-rc.d -f stream remove
rm -fv "$0"
fi
}

case "$1" in
start)
start
;;
stop)
stop
;;
uninstall)
uninstall
;;
retart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart|uninstall}"
esac
 
Old 05-16-2014, 06:12 PM   #8
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Most likely you have a quoting failure...

It is one of the difficulties of shell programming - when the parameters get long, and you try to pass the entire string as a parameter to something else that is going to interpret the string..

It is hard to get right.

One thing you can do to test things is to run it manually:

sh -vx stream start >& errorlog

This should fail as you have seen, but the recording in "errorlog" will show each step of the script, AND show how each line/variable gets expanded.
 
Old 05-17-2014, 02:57 AM   #9
tonj
Member
 
Registered: Sep 2008
Posts: 546

Original Poster
Rep: Reputation: 37
@jpollard: I think you misunderstand. The command works, that's not the problem. The essence of this topic is how to break the long line down in the script into shorter lines so it all fits in the console window and so it still works when it's run.
 
Old 05-17-2014, 05:12 AM   #10
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
You have said this script works, I am not sure how as there are a number of typos and even a variable which does not exist but is called (namely PIDNAME).

So i will point out that all startup scripts are generally run as root so not only do I not see the point of your RUNAS variable, I see no point to the entire call to su?
If you think about it, if you were really calling su to change yourself to root, you would need to enter the password, which would seem mute at startup as there would
be nowhere to capture this information.

Finally, jpollard does not misunderstand and is exactly correct ... ie apart from escaping the end of the line to create the continuation, how you have quoted is the biggest issue.
To demonstrate using your original example:
Code:
SCRIPT="ffmpeg -i "rtmp://<ip-camera>" \
-f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast \
-crf 35 -c:a libfdk_aac -ac 1 -ab 32k \
-vf drawtext="fontfile=/usr/share/fonts/truetype/arialbd.ttf: \
text='livebit.co.uk':fontsize=20:fontcolor=white:x=30:y=310" \
"rtmp://198.91.92.244:2501/live/livestream1""
Here I have colour coded all the matching sets of double quotes you have used. If you look at where you see the colour first appearing and then where it ends, you will notice that a great deal of your
code is not quoted at all, point in case - the last set of quotes is at the end of everything with nothing between them

Were it quoted correctly:
Code:
SCRIPT="ffmpeg -i 'rtmp://<ip-camera>' \
-f flv -r 10 -s 640x360 -vcodec libx264 -preset veryfast \
-crf 35 -c:a libfdk_aac -ac 1 -ab 32k \
-vf drawtext=\"fontfile=/usr/share/fonts/truetype/arialbd.ttf: \
text='livebit.co.uk':fontsize=20:fontcolor=white:x=30:y=310\" \
'rtmp://198.91.92.244:2501/live/livestream1'"
Now you made need to finesse it a little but this gives you an idea of just how important quoting is.
 
Old 05-17-2014, 07:53 AM   #11
JeremyBoden
Senior Member
 
Registered: Nov 2011
Location: London, UK
Distribution: Debian
Posts: 1,947

Rep: Reputation: 511Reputation: 511Reputation: 511Reputation: 511Reputation: 511Reputation: 511
Code:
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"
How many errors are present?
 
Old 05-17-2014, 09:39 AM   #12
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
At least two...

1. su isn't needed to run a root process (it already is).

2. The CMD gets turned into multiple redirects... and the "LOGFILE" may not be a log file... (remember, the $SCRIPT is expanded..

As the "CMD" and "LOGFILE" environment variables are expanded for the assignment there can easily be more quoting peculiarities - things you expect to be quoted won't be, things you didn't expect might be...

And when SCRIPT is expanded you again get quoting reinterpreted...

It is very very hard to get such quoting right.

It would be much simpler to do:
Code:
ffmpeg -i "rtmp://<ip-camera>" \
         -f flv \
         -r 10 \
         -s 640x360 \
         -vcodec libx264 \
         -preset veryfast \
         -crf 35 \
         -c:a libfdk_aac \
         -ac 1 \
         -ab 32k \
         -vf drawtext="fontfile=/usr/share/fonts/truetype/arialbd.ttf: text='livebit.co.uk':fontsize=20:fontcolor=white:x=30:y=310" \
         "rtmp://198.91.92.244:2501/live/livestream1" \
              >& $LOGFILE &
echo $! >$PIDFILE
And if you needed it to run detatched, add the "nohup" command at the beginning.

I have always found this form simplifies handling the quoting, and allows each option to be examined independently.
 
1 members found this post helpful.
Old 05-17-2014, 10:42 AM   #13
tonj
Member
 
Registered: Sep 2008
Posts: 546

Original Poster
Rep: Reputation: 37
@grail thankyou for your help, you solved it. Using ' instead of " worked and I am now able to break this long command down into several lines in the script, I can see the whole string clearly and the command works when the script is started.
 
Old 05-17-2014, 11:08 AM   #14
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Please use the Thread Tools to mark the question as SOLVED
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Console does not wrap long lines z-vet Linux - Software 11 10-10-2013 04:05 AM
wrap lines at 80 for long aliases in .aliases.csh jhwilliams Linux - Software 0 07-26-2007 07:49 AM
console command display wrap nathanv117 SUSE / openSUSE 3 12-02-2004 10:38 AM
bash does not wrap long lines correctly monkeyman2000 Linux - General 8 09-08-2004 09:30 PM
Wrap up of the /sbin/route command acura94 Programming 1 09-11-2002 03:52 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 11:50 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration