2

I have a simple function to open an editor:

open_an_editor()
{
    nano "$1"
}

If called like open_an_editor file.ext, it works. But if I need to get some output from the function — smth=$(open_an_editor file.ext) — I cannot see the editor, script just stucks. What am I missing here?

Update: I am trying to write a function which would ask the user to write a value in editor, if it wasn't given in script arguments.

#!/bin/bash
open_an_editor()
{
    if [ "$1" ]
    then
        echo "$1"
        return 0
    fi
    tmpf=$(mktemp -t pref)
    echo "default value, please edit" > "$tmpf"

    # and here the editor should show up,
    # allowing user to edit the value and save it

    # this will stuck without showing the editor:
    #nano "$tmpf"

    # but this, with the help of Kimvais, works perfectly:
    nano "$tmpf" 3>&1 1>&2 2>&3

    cat "$tmpf"
    rm "$tmpf"
}

something=$(open_an_editor "$1")
# and then I can do something useful with that value,
# for example count chars in it
echo -n "$something" | wc -c

So, if the script was called with an argument ./script.sh "A value", the function would just use that and immediately echo 7 bytes. But if called without arguments ./script.sh — nano should pop up.

Johnny Woo
  • 187
  • 1
  • 4
  • 10
  • 1
    Exactly what output are you expecting from the editor? – Ignacio Vazquez-Abrams Mar 02 '10 at 05:59
  • what are you trying to do? make it more clear – ghostdog74 Mar 02 '10 at 06:02
  • I think you meant A\ value :) You can use 'tr' to escape spaces properly prior to passing it to your editor of choice. Its not the editor, its VFS and the underlying file system. Spaces are just as acceptable as non spaces when it comes to file names, but they have to be escaped. tr ' ' '\ ' might be a start. – Tim Post Mar 02 '10 at 10:02

3 Answers3

2

If the input you need is the edited file, then you obviously need to cat filename after you do the open_an_editor filename

If you actually need the output of the editor, then you need to swap stderr and stdin i.e: nano "$1" 3>&1 1>&2 2>&3

If yo need 'friendly' user input, see this question on how to use whiptail

Community
  • 1
  • 1
Kimvais
  • 38,306
  • 16
  • 108
  • 142
  • Thanks a lot! What should I google to understand what exactly this swapping does? :) – Johnny Woo Mar 02 '10 at 09:49
  • 1
    The swapping is similar to `tmp = a; a = b; b = tmp;` statements to swap the values of `a` and `b`. Here, file descriptor 3 is `tmp`, and 1, 2 are `a`, `b`. 1 is stdout, 2 is stderr. – Alok Singhal Mar 02 '10 at 09:56
  • 1
    Addition to comment by @Alok - 0,1,2 are pre-defined __file descriptors__ that point to standard input, output and error (respectively) - other file descriptors are in general 'generated' by calling open() function in programming language. However, in the swapping example the fd 3 - is directed to fd 1, and hence can be used without Here's a link about them http://en.wikipedia.org/wiki/File_descriptor As a bonus, you can see the "already in use" file descriptors in your current shell by `ls /proc/$$/fd` – Kimvais Mar 03 '10 at 07:16
0

if you need to get output from function and store in variable, you just display what's in file.

open_an_editor()
{
    cat "$1"
}
smth=$(open_an_editor file.txt)
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
0

If all you want is for a user to enter a value then read is enough:

OLDIFS="$IFS"
IFS=$'\n'
read -p "Enter a value: " -e somevar
IFS="$OLDIFS"
echo "$somevar"
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358