0

For web-development practice I'm using a LAMP stack, on Ubuntu 17.10. For this I'm creating directories within /var/www, each directory is named after a project.

To create a subdirectory I use the terminal and:

david@Ed:/var/www/html$ mkdir projectName
david@Ed:/var/www/html$ cd projectName
david@Ed:/var/www/html/projectName$ mkdir css img js
david@Ed:/var/www/html/projectName$ touch index.html
david@Ed:/var/www/html/projectName$ ls
css  img  index.html  js

This works. And, in all honesty, is far from arduous. But, is there a means by which I can simplify this?

I'm aware that:

mkdir -p projectName/css

Will create both the css, and the parent projectName, directory (if that parent doesn't already exist), but it still leaves the requirement of creating the other two directories and the index.html file (again, this is not particularly arduous but feels like it should be unnecessary).

Ideally I'd like that the command mkdir <projectName> when run in the /var/www directory would create the <projectName> directory with the css, img, js directories and the index.html document (that document ideally containing the skeleton of a valid html document*). However I accept that abusing the mkdir command would likely lead to unforeseen/predictable edge-cases and consequences, so probably the best compromise is a script of some kind.

With the above in mind, I created the following (naive/simple) script:

#!/bin/bash
mkdir $@
cd $@
mkdir css img js
touch index.html

I call the above script as follows:

./createDir.sh projectName

This works but is less than ideal; the problems:

  1. the created index.html has a type of plain text document (text/plain), rather than the expected HTML document (text/html), and of course
  2. has none of the structure of an HTML document (as outlined in the single footnote), because I didn't add any content (and haven't yet found a way of creating said content in a script).

Also, somewhat predictably, both the css and js directories would also – ideally – be created with documents (project.css and project.js) intact.

So, is there a means by which I can create – with the use of a script, or otherwise – a directory with its subdirectories and documents?


*. As a rudimentary example:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="js/project.js"></script>
  <link href="css/project.css" rel="stylesheet" />
</head>
<body></body>
</html>
  • Related: Create file and its parent directory – steeldriver Aug 4 '18 at 17:14
  • what is wrong with mkdir -p projectName/{css,js,img}? Plus you can add a && touch projectName/index.html to create the file, or use a cp to copy a index.html to this location. – Rinzwind Aug 4 '18 at 17:17
  • @Rinzwind: absolutely nothing is wrong with it, except that I hadn't come across that syntax before and didn't know of its existence. I do like - and hadn't considered - the approach of copying existing template files. Thank you. – David says reinstate Monica Aug 4 '18 at 17:22
  • @DavidThomas well you can also create the file on the fly by doing a "echo {content} > index.html" ;) – Rinzwind Aug 4 '18 at 17:28
  • 1
    I would just like to point out that creating a user with adduser does something similar. For that purpose skeleton is used, which is in fact a template like proposed in some answers. If you make a template/skeleton with all directories and files, the only thing you need is copy (cp -fvr <template> <destination>) after creating a directory for a new project. – nobody Aug 4 '18 at 17:49
1

I would suggest you to do something like adduser command is doing with skeleton (https://unix.stackexchange.com/questions/285708/skeleton-directory-how-to-add-my-own-directories).

Make a template/skeleton somewhere, where all the initial files and directories for the project are organized as they would be in the project. After you make a directory for a new project you just copy the skeleton to the destination with a simple copy:

cp -fvar <template directory> <destination directory>

The parameters in cp command are as follows:

f - force overwrite if destination already exists
v - verbose to show what is being copied
a - archive to preserve file permissions and ownerships
r - recursive to copy all directories and files.

I would point out here an archive parameter, which allows you to set the correct files and directories permissions and ownerships in the template. They will be preserved when copied and in that way you have files in the project with correct permissions for web server to access them. If you want to have different ownerships of files for each project, you will have to do that manually, again with simple commands (chmod -R <permissions> <destination directory> and chown -R <ownership> <destination directory).

|improve this answer|||||
1

You'll need some template for your index.html to copy from. But you can create such a template on the fly and then copy it to the desired destination. The install command may be of help:

#!/usr/bin/env bash

template=$(mktemp);     # creates a temporary file, usually in /tmp

# Add the HTML code to that temporary file:
cat << EOF > $template
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="js/project.js"></script>
  <link href="css/project.css" rel="stylesheet" />
</head>
<body></body>
</html>
EOF

# "Install" the file with the given mode 
# and create any intermediate directories:
install -m 0644 -D $template /var/www/html/projectName/index.html

# remove the temporary file
rm $template;

exit 0;

You probably need to run this script via sudo because /var/... isn't world-writable.

|improve this answer|||||
0

While this is an imperfect answer, and is mostly produced via some further searches after I posted the question, I've updated my script and solved most of the the problems.

My current script (equally naive and simple though it certainly is) is:

#!/bin/bash
mkdir $@
cd $@
mkdir css img js
cat > index.html <<- "EOF"
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="js/project.js"></script>
  <link href="css/project.css" rel="stylesheet" />
</head>
<body></body>
</html>
EOF
cat > css/project.css <<- "EOF"
*, ::before, ::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
EOF
cat > js/project.js <<- "EOF"
;
EOF

This feels a little dirty, though it does work. The main issue with this, current, approach is that final cat call:

cat > js/project.js <<- "EOF"
;
EOF

This to produce a document that is correctly identified by its type property as application/javascript, whereas using:

touch js/project.js

Simply creates yet another document – with the correct filetype extension – whose type attribute is plain text document (text/plain).

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.