g | x | w | all
Bytes Lang Time Link
073AWK250729T194028Zxrs
108Bash and seq250616T100214ZAsturio
087Bash250616T110415Zmanatwor
089JavaScript250613T101046ZMiro
068Python 3160928T200029Z0WJYxW9F
099tcl170704T214133Zsergiol
105Python170704T190209ZЕвгений
025APL Dyalog Unicode170704T164548ZAdá
087C160919T214927Zuser5898
108Racket161002T034426Zrnso
074PHP160918T133413ZJör
070Python160919T044823ZFabien B
089bash160918T141758ZThor
104Common Lisp160918T142747Zuser5981
093C#160919T090717Zadrianmp
131F#160920T011140Zuser5985
093Lua160919T040221ZATaco
006Jolf160920T003438ZConor O&
048Perl160919T163550ZTon Hosp
095Python 3160919T121856Zuser5985
052Ruby160918T133424Zdaniero

AWK, 73 bytes

{for(;i++<$2;)for(j=0;j++<$1;)printf 1~j?"|":$1~j?"|\n":1~i||$2~i?"-":FS}

Attempt This Online!

Just writes char by char, line by line. Couldn't seem to save space with fancy functions.

Bash and seq, 132 108 bytes

    b(){ echo -n "|";for i in $(seq 3 $1);do echo -n "$2";done;echo "|";}
    r(){ b $1 "-";for i in $(seq 3 $2);do b $1 " ";done;b $1 "-";}

Use calling r, like r 8 4:

|------|
|      |
|      |
|------|

Update with manatwork suggestions, reducing to 108 byte (not EOL in the last line):

b(){ echo "|`for i in $(seq 3 $1);{ echo -n "$2";}`|";}
r(){ b $1 -;for i in `seq 3 $2`;{ b $1 \ ;};b $1 -;}

Bash, 87 characters

Inspired by Asturio's solution.

printf -vl '|%*s|' $[$1-2]
h=${l// /-}
echo $h
for((i=2;i++<$2;));{ echo "$l";}
echo $h

Try it online!

JavaScript, 89 bytes

f=(w,h)=>{s=`|${"-".repeat(w-2)}|`;return s+`
`+("|"+" ".repeat(w-2)+`|
`).repeat(h-2)+s}

Python 3, 68 bytes

def f(a,b):
 c='|'+'-'*(a-2)+'|\n';print(c+c.replace(*'- ')*(b-2)+c)

tcl, 99

puts [set M |[string repe - [incr w -2]]|]
incr w
time {puts |[format %$w\s |]} [incr h -2]
puts $M

demo

Python, 105 bytes

[a,b]=input().split()
def d(e):print("|"+e*(int(a)-2)+"|")
d("-")
for f in range(2,int(b)):d(" ")
d("-")

Try it online

APL (Dyalog Unicode), 25 bytes

'|','|',⍨'-'⍪'-'⍪⍨''⍴⍨-∘2

Try it online!

-∘2 subtract two

''⍴⍨ use that as height and width to reshape an empty string (padding with spaces)

'-'⍪⍨ put dashes below

'-'⍪ put dashes on top

'|',⍨ put stiles on the right

'|', put stiles on the left

C 87 bytes

f(b,a,c,k){for(;c<a*b;++c)printf("%s",(k=c%b)==b-1?"|":!k?"\n|":c<b||c>a*b-b?"-":" ");}

this is the main for some test...

main() 
{f(3,3,0,0); f(5,8,0,0); f(10,3,0,0);
 return 0;
}


|-|
| |
|-|
|---|
|   |
|   |
|   |
|   |
|   |
|   |
|---|
|--------|
|        |
|--------|

Racket 108 bytes

(λ(w h)(for((j h))(display #\|)(for((i(- w 2)))(display(if(or(= j 0)(= j(- h 1)))#\-" ")))(displayln #\|)))

Ungolfed:

(define f
  (λ (w h)
    (for ((j h)) 
      (display #\|)
      (for ((i (- w 2)))
        (display (if (or
                      (= j 0)
                      (= j (- h 1)))
                     #\-
                     " ")))
      (displayln #\|))))

Testing:

(f 5 3)

Output:

|---|
|   |
|---|

PHP, 74 Bytes

for(;$i<$n=$argv[2];)echo str_pad("|",$argv[1]-1,"- "[$i++&&$n-$i])."|\n";

Python (70 bytes)

def r(w,h): print '\n'.join(['|'+('-' if i%(h-1)==0 else ' ')*(w-2)+'|' for i in range(h)])

Edit: lambda function for a few less bytes (thanks @DJMcMayhem)

r=lambda w,h:'\n'.join(['|'+('-'if i%(h-1)==0 else' ')*(w-2)+'|'for i in range(h)])

Edit#2: if notation is greedy

r=lambda w,h:'\n'.join(['|'+(0<i<h-1 and' 'or'-')*(w-2)+'|'for i in range(h)])

Edit#3: -8 bytes with list trick

r=lambda w,h:'\n'.join(['|'+'- '[0<i<h-1]*(w-2)+'|'for i in range(h)])

bash, sed and coreutils, 95 89 bytes

You can define a function like this

f(){ n=$[$1-2];yes \ |sed $[$2*n]q|tr -d \\n|fold -w$n|sed 's/^\|$/|/g;1!{$!b};s/ /-/g';}

Or in a more readable format:

f() { 
  n=$(($1-2))
  
  # The next couple of lines create a rectangle of spaces
  # matching the desired size
  yes ' '          |
  head -n$(($2*n)) |
  tr -d '\n'       |
  fold -w$n        |

  # Add the pipes and dashes
  sed '
    s/^\|$/|/g   # Replace first and last character by a pipe
    1! {$!b }    # Do nothing if not on first or last line
    s/ /-/g      # Add the dashes
  '
  echo
}

You can now say f 4 3:

|--|
|  |
|--|

If you care about trailing new-line, add an echo at the end of function.

Common Lisp, 104 bytes

Golfed:

(defun a(w h)(flet((f(c)(format t"|~v@{~A~:*~}|~%"(- w 2)c)))(f"-")(loop repeat(- h 2)do(f" "))(f"-")))

Ungolfed:

(defun a (w h)
  (flet ((f (c) (format t "|~v@{~A~:*~}|~%" (- w 2) c)))
    (f "-")
    (loop repeat (- h 2) do
     (f " "))
    (f "-")))

C#, 102 93 bytes

Saved 9 bytes thanks to milk - completely forgot to concatenate strings. The compare trick is pretty cool too.

w=>h=>{var s="";for(int i=0;i<h;)s+="|"+new String(1>i++%(h-1)?'-':' ',w-2)+"|\n";return s;};

Try it online!

Full source, including test cases:

using System;

namespace DrawASCIIRectangle
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int,Func<int,string>> d= w=>h=>{var s="";for(int i=0;i<h;)s+="|"+new String(1>i++%(h-1)?'-':' ',w-2)+"|\n";return s;};
            Console.WriteLine(d(3)(3));
            Console.WriteLine(d(5)(8));
            Console.WriteLine(d(10)(3));
        }
    }
}

F#, 131 bytes

let d x y=
 let q = String.replicate (x-2)
 [for r in [1..y] do printfn "%s%s%s" "|" (if r=y||r=1 then(q "-")else(q " ")) "|"]

Lua, 120 93 bytes

Saved quite a few bytes by removing stupid over complexities.

function(w,h)function g(s)return'|'..s:rep(w-2)..'|\n'end b=g'-'print(b..g' ':rep(h-2)..b)end

Ungolfed:

function(w,h)                           -- Define Anonymous Function
    function g(s)                       -- Define 'Row Creation' function. We use this twice, so it's less bytes to function it.
        return'|'..s:rep(w-2)..'|\n'    -- Sides, Surrounding the chosen filler character (' ' or '-'), followed by a newline
    end
    b=g'-'                              -- Assign the top and bottom rows to the g of '-', which gives '|---------|', or similar.
    print(b..g' ':rep(h-2)..b)          -- top, g of ' ', repeated height - 2 times, bottom. Print.
end

Try it on Repl.it

Jolf, 6 bytes

,ajJ'|

Try it here! My box builtin finally came in handy! :D

,ajJ'|
,a       draw a box
  j      with width (input 1)
   J     and height (input 2)
    '    with options
     |    - corner
          - the rest are defaults

Perl, 48 bytes

Includes +1 for -n

Give sizes as 2 lines on STDIN

perl -nE 'say"|".$_ x($`-2)."|"for"-",($")x(<>-1-/$/),"-"'
3
8
^D

Just the code:

say"|".$_ x($`-2)."|"for"-",($")x(<>-1-/$/),"-"

Python 3, 104 95 bytes

( feedback from @mbomb007 : -9 bytes)

def d(x,y):return'\n'.join(('|'+('-'*(x-2)if n<1or n==~-y else' '*(x-2))+'|')for n in range(y))

(my first code golf, appreciate feedback)

Ruby, 59 54 52 bytes

Oh, that's a lot simpler :)

->x,y{y.times{|i|puts"|#{(-~i%y<2??-:' ')*(x-2)}|"}}

Test run at ideone