aboutsummaryrefslogtreecommitdiff
path: root/doc/functions.txt
blob: 3954c44063edecb438c9b925709c46b41b19aacb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
FUNCTIONS
=================================================================================

This is a document for example functions to ensure portability across different
systems. These are mere examples as we currently depend on non-POSIX utilities on
packages. These dependencies will be removed as we go forward.

I don't want to turn the functions in here into a library because these are
really simple, and I believe that the build scripts should be self-contained.
What's the point of creating portable functions if the functions themselves
depend on a library file to be installed on a system?

These obviously have their own limitations, but not every limitation has to be
solved in a single function. Use your imagination, non-standard flags/commands
may save you some keypresses, but they are not standard, because you can already
do these with your brain and a few more keypresses.

SED -i
---------------------------------------------------------------------------------

The -i function isn't portable across systems, and isn't defined by POSIX. But it
isn't too valuable as it can be replaced with a simple function. I present you
sed_i. This function only depends on the fact that the file name is the last
argument.


    sed_i() {
        # This makes sure that we store the last argument on
        # a file variable.
        for file; do :; done

        # Run the arguments against sed, and redirect output
        # to a temporary file simply named '_'.
        sed "$@" > _
        # Instead of moving we cat into the file. This way we
        # do not have to worry about preserving permissions of
        # the file
        cat _ > "$file"; rm -f _
    }

In build scripts with multiple 'sed -i' usage, such a function can be defined for
and used. If only it is used a single time, defining such a function is quite
unnecessary. In such a case prefer doing it manually. Assume the file is named
'file.h' and we are calling 's/this/that/g'.


    sed 's/this/that/g' file.h >_
    cat _ > file.h; rm -f _


INSTALL -D,-t
---------------------------------------------------------------------------------

'install' does not have a standard. Options such as '-D' and '-t', even though
they are the most used, do not exist on every implementation. Avoid using these
flags where possible. You can prefer using functions such as these. The first
function is similar to '-t' flag, where you can install multiple files to a given
target. The second function is similar to the usage without the '-t' flag, a
single file where it will be named as the argument.


    kinstall_t() {
         # usage: kinstall_t 755 /usr/bin file1 file2 file3
         mod=$1 dir=$2; mkdir -p "$dir"
         shift 2
         for file; do
             ! [ -d "$dir/$file" ] || {
                 printf '%s\n' "Error: $dir/$file is a directory >&2"
                 return 1
             }
             cp "$file" "$dir"
             chmod "$mod" "$dir/$file"
         done
    }


    kinstall() {
        # usage: kinstall 755 filename /usr/bin/file
        ! [ -d "$3" ] || {
            printf '%s\n' "Error: $target is a directory" >&2
            return 1
        }
        mkdir -p "${3%/*}"; cp "$2" "$3"
        chmod "$1" "$3"
    }