LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   SOLVED: trying to wrap long command (https://www.linuxquestions.org/questions/linux-newbie-8/solved-trying-to-wrap-long-command-4175505220/)

tonj 05-16-2014 10:26 AM

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?

szboardstretcher 05-16-2014 10:30 AM

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?

tonj 05-16-2014 10:58 AM

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.

grail 05-16-2014 11:09 AM

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??

tonj 05-16-2014 11:19 AM

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.

szboardstretcher 05-16-2014 11:42 AM

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.

tonj 05-16-2014 04:29 PM

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

jpollard 05-16-2014 06:12 PM

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.

tonj 05-17-2014 02:57 AM

@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.

grail 05-17-2014 05:12 AM

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.

JeremyBoden 05-17-2014 07:53 AM

Code:

local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"

How many errors are present?

jpollard 05-17-2014 09:39 AM

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.

tonj 05-17-2014 10:42 AM

@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.

grail 05-17-2014 11:08 AM

Please use the Thread Tools to mark the question as SOLVED


All times are GMT -5. The time now is 04:58 PM.